React笔记(一)
2024 年 5 月 3 日 星期五(已编辑)
/
14
摘要
这段内容主要介绍了如何创建React程序,React的渲染流程,JSX的本质以及基础事件绑定。同时还介绍了React组件的基本类型和数据传递,以及如何使用useState来管理状态。最后也提到了React样式的基本用法。
这篇文章上次修改于 2024 年 5 月 7 日 星期二,可能部分内容已经不适用,如有疑问可询问作者。
阅读此文章之前,你可能需要首先阅读以下的文章才能更好的理解上下文。
1.创建React程序
npx create-react-app 项目名
React渲染流程
App.js -> index.js -> index.html(root)
JSX本质
JS的扩展语法(语法糖),通过解析工具解析后在浏览器中运行
JSX的本质是将类似XML的标记转换为JavaScript对象。当编写JSX代码时,开发者 可以使用类似HTML的标签和属性,但在底层,这些标记会被转换为React.createElement()函数的调用,返回一个描述UI元素的JavaScript对象。
转换前
const element = <h1 className="greeting">Hello, World!</h1>;
转换后
const element = React.createElement('h1', { className: 'greeting' }, 'Hello, World!');
JSX通过{ }来识别JS的表达式
const count = 100;
function getCount() {
return count;
}
function countDelete(){
for (var i = 0; i < count; i++){
console.log(i);
}
}
function App() {
return (
<div className="App">
this is App
{/* 变量调用 */}
<div>{count}</div>
{/* 函数调用 */}
<div>{getCount()}</div>
<div>{countDelete()}</div>
{/* 方法调用 */}
{new Date().getDate()}
{/* 识别对象 */}
<div style={{color:'red'}}>hello world</div>
</div>
);
}
export default App;
渲染
列表渲染(通过key来唯一标识加速渲染)
const list = [
{ id: 1001,name: 'Vue' },
{ id: 1002,name: 'React' },
{ id: 1003,name: 'Angular' }
]
function App() {
return (
<div className="App">
<ul>
{list.map(item=><li key={item.id}>{item.id}--{item.name}</li>)}
</ul>
</div>
);
}
export default App;
条件渲染(React通过逻辑运算符和三元表达式来实现基础条件渲染)
const loading = 0;
const isLogin = true;
function App() {
return (
<div className="App">
{isLogin && <p>you are login in</p>}
{loading?<span>loading...</span>:<span>this is a span</span>}
</div>
);
}
复杂条件渲染
const target = 3
function getArticle() {
if(target === 0) {
return <div>无图模式</div>
}else if(target === 1) {
return <div>单图模式</div>
}else if(target === 3) {
return <div>多图模式</div>
}
}
function App() {
return (
<div className="App">
{getArticle()}
</div>
);
}
React基础事件绑定
function App() {
function clickHandler() {
return alert("hello world")
}
return (
<div className="App">
<button onClick={clickHandler}>button</button>
</div>
);
}
//事件参数e
function App() {
const clickHandler = (e) => {
console.log(e)
}
return (
<div className="App">
<button onClick={clickHandler}>button</button>
</div>
);
}
//传自定义值
function App() {
const clickHandler = (name) => {
console.log(name)
}
return (
<div className="App">
<button onClick={()=>clickHandler('jack')}>button</button>
</div>
);
}
//即传事件参数又传自定义值
function App() {
const clickHandler = (name, e) => {
console.log(e,name)
}
return (
<div className="App">
<button onClick={(e) => clickHandler('jack', e)}>button</button>
</div>
);
}
2.React常用的事件绑定
onClick事件:
class MyComponent extends React.Component {
handleClick = () => {
// 处理点击事件的逻辑
};
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
onChange事件(通常用于表单元素):
class MyForm extends React.Component {
handleChange = (event) => {
// 处理输入值变化的逻辑
};
render() {
return (
<input type="text" onChange={this.handleChange} />
);
}
}
onSubmit事件(通常用于表单提交):
class MyForm extends React.Component {
handleSubmit = (event) => {
// 处理表单提交的逻辑
event.preventDefault(); // 阻止默认的表单提交行为
};
render() {
return (
<form onSubmit={this.handleSubmit}>
{/* 表单内容 */}
<button type="submit">Submit</button>
</form>
);
}
}
其他常见事件(例如鼠标悬停):
class MyComponent extends React.Component {
handleMouseOver = () => {
// 处理鼠标悬停的逻辑
};
render() {
return (
<div onMouseOver={this.handleMouseOver}>
Hover over me
</div>
);
}
}
3.React组件
在React中,组件是构建用户界面的基本单元,可以是函数组件或类组件。组件可以包含其他组件,形成组件树,这样整个应用程序的界面就被分解成了独立且可复用的部分。以下是React中常见的组件类型和一些示例:
函数组件: 使用函数声明的组件,接收一个
props
对象作为参数,返回一个React元素。函数组件是无状态的,通常用于简单的UI部分。function MyFunctionalComponent(props) { return <div>Hello, {props.name}!</div>; }
类组件: 使用ES6类语法声明的组件,继承自
React.Component
。类组件有自己的状态(state)和生命周期方法,适用于需要内部状态或生命周期处理的情况。class MyClassComponent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } render() { return <div>Count: {this.state.count}</div>; } }
使用Hooks的函数组件: 使用Hooks(如
useState
和useEffect
)可以在函数组件中使用状态和生命周期等功能。import React, { useState, useEffect } from 'react'; function MyFunctionalComponentWithHooks() { const [count, setCount] = useState(0); useEffect(() => { // 处理副作用,类似于componentDidMount和componentDidUpdate document.title = `Count: ${count}`; }, [count]); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); }
组件之间的数据传递: 父组件可以通过
props
向子组件传递数据,子组件可以通过回调函数将数据传递回父组件。//ParentComponent.jsx import React from 'react'; import ChildComponent from './ChildComponent'; function ParentComponent() { const handleChildData = (data) => { console.log(`Data from child: ${data}`); }; return <ChildComponent onData={handleChildData} />; }
// ChildComponent.jsx import React from 'react'; function ChildComponent({ onData }) { const sendDataToParent = () => { const data = 'Hello from child!'; onData(data); }; return ( <div> <button onClick={sendDataToParent}>Send Data</button> </div> ); }
自测
function handerTest() {
alert('hello world')
}
function Button() {
return <button onClick={handerTest}>click me!</button>
}
function App() {
return (
<div className="App">
<Button />
</div>
);
}
浏览器waring
[Violation] 'click' handler took 1189ms
[Violation] 'click' handler took 1189ms
react-dom.development.js:4161 [Violation] 'click' handler took 864ms
[Violation] 'click' handler took 867ms
解释
这些警告信息是浏览器开发者工具提供的性能提示,它们指示在处理点击事件时花费的时间较长。这可能是由于事件处理函数中执行的操作过于耗时,导致页面性能下降。
要解决这个问题,可以考虑以下几点:
优化事件处理函数: 确保事件处理函数内的代码是高效的。避免在事件处理函数中执行复杂或耗时的操作,尤其是在用户与页面交互时。如果有必要执行长时间运行的任务,可以考虑使用异步操作或将其拆分成多个步骤。
懒加载和分割代码: 如果应用程序包含大量代码,可以考虑使用懒加载(Lazy Loading)和代码分割(Code Splitting)来延迟加载部分代码。这有助于减少初始加载时的工作量,提高页面响应速度。
性能分析工具: 使用浏览器提供的性能分析工具,例如Chrome的Performance面板,来检查哪些部分的代码执行时间较长。这有助于定位性能瓶颈并进行优化。
React性能优化: 使用React提供的性能优化技术,例如React.memo、useMemo和useCallback,以避免不必要的重新渲染和函数重复执行。
修改后
import React, { useCallback } from 'react';
function Button() {
const handleClick = useCallback(() => {
// 你的点击事件处理逻辑
alert('hello world');
}, []);
return <button onClick={handleClick}>点击我!</button>;
}
4.useState
useState是一个Hook 函数,允许我们向组件传递一个状态变量,通过状态变量的值来影响组件的渲染(数据驱动视图)
const [count,setCount] = useState(0)
//useState是一个函数,返回值是一个数组
//数组的第一个参数是状态变量,第二个参数是set函数用来修改状态变量
//useState的参数将作为count的初始值
import { useState } from 'react';
//简易计数器
function App() {
const [count, setCount] = useState(0)
const handleClick = ()=> {
setCount(count+1)
}
return (
<div className="App">
<button onClick={handleClick}>{count}</button>
</div>
);
}
复杂类型对象
import { useState } from 'react';
function App() {
const [Form, setForm] = useState({name: 'linmo'})
const handleClick = ()=> {
setForm({
...Form,
name: 'limin'
})
}
return (
<div className="App">
<button onClick={handleClick}>{Form.name}</button>
</div>
);
}
状态不可变
在React中,状态被认为只是可读的,我们应该始终替换它而不是修改它,即不通过setCount函数,直接修改状态变量不会引发组件视图的更新
5.React样式基础
//导入样式
import './index.css'
function App() {
return (
<div className="App">
<p className='test'>hello world</p>
</div>
);
}