七、React 事件处理与性能优化
React 事件处理采用 合成事件(SyntheticEvent),它是 React 对原生事件的封装,提供了更好的跨浏览器兼容性和性能优化。
(一)事件绑定
1. 基本事件绑定
jsx
function Button() {
return <button onClick={() => alert("Clicked!")}>Click Me</button>;
}
2. 在类组件中绑定事件
jsx
class App extends React.Component {
handleClick() {
alert("Clicked!");
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
问题 :this.handleClick
没有绑定 this
,导致 this
为 undefined
。
解决方案:
-
方法 1:使用箭头函数(推荐)
jsx<button onClick={() => this.handleClick()}>Click Me</button>
-
方法 2:在构造函数中绑定
this
jsxconstructor(props) { super(props); this.handleClick = this.handleClick.bind(this); }
(二)事件对象 event
React 事件处理函数会接收一个 合成事件(SyntheticEvent),它与原生事件类似,但性能更优。
jsx
function Button() {
const handleClick = (event) => {
console.log(event.target); // 获取触发事件的元素
};
return <button onClick={handleClick}>Click Me</button>;
}
阻止默认行为
jsx
function Link() {
return (
<a href="https://react.dev" onClick={(e) => e.preventDefault()}>
Click me (but won't navigate)
</a>
);
}
事件冒泡 & 阻止事件传播
jsx
function Parent() {
const handleParentClick = () => console.log("Parent Clicked!");
const handleChildClick = (event) => {
event.stopPropagation(); // 阻止事件冒泡
console.log("Child Clicked!");
};
return (
<div onClick={handleParentClick}>
<button onClick={handleChildClick}>Click Me</button>
</div>
);
}
(三)事件传参
传递参数
jsx
function Button({ name }) {
const handleClick = (name, event) => {
console.log(`Hello, ${name}`);
};
return <button onClick={(e) => handleClick(name, e)}>Click Me</button>;
}
(四)性能优化
React 在事件处理上进行了优化,但仍需开发者手动优化。
1. 使用 useCallback
避免函数重复创建
jsx
const handleClick = useCallback(() => {
console.log("Clicked!");
}, []);
2. 使用 useMemo
避免不必要的计算
jsx
const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
3. 使用 React.memo
避免组件重复渲染
jsx
const Child = React.memo(({ value }) => {
console.log("Child Rendered");
return <div>{value}</div>;
});
4. 使用 shouldComponentUpdate
进行类组件优化
jsx
class Example extends React.Component {
shouldComponentUpdate(nextProps) {
return nextProps.value !== this.props.value;
}
}
八、React 状态管理
React 的组件可以使用 useState
进行状态管理,但当组件层级较深时,状态管理会变得复杂。
(一)Context API(适用于全局状态共享)
1. 创建 Context
jsx
const ThemeContext = React.createContext();
2. 提供数据
jsx
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
3. 消费数据
jsx
function Toolbar() {
return (
<ThemeContext.Consumer>
{(theme) => <div>Current Theme: {theme}</div>}
</ThemeContext.Consumer>
);
}
推荐使用 useContext
简化写法:
jsx
function Toolbar() {
const theme = useContext(ThemeContext);
return <div>Current Theme: {theme}</div>;
}
(二)Redux(适用于大规模应用)
Redux 通过 单一数据源(Store) 和 纯函数(Reducer) 管理应用状态。
1. 创建 Redux Store
jsx
import { createStore } from "redux";
const reducer = (state = { count: 0 }, action) => {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
default:
return state;
}
};
const store = createStore(reducer);
2. 订阅 Store
jsx
store.subscribe(() => console.log(store.getState()));
3. 触发 Action
jsx
store.dispatch({ type: "INCREMENT" });
4. 结合 React
使用 react-redux
提供的 Provider
:
jsx
import { Provider } from "react-redux";
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
九、React 18 重要优化
(一)自动批量更新(Automatic Batching)
React 18 以前,多个 setState
会触发多次渲染:
jsx
setCount(count + 1);
setName("React");
React 18 之后,这些状态更新会自动合并,提高性能。
(二)并发渲染(Concurrent Rendering)
React 18 引入 并发模式,允许多个渲染任务同时进行,避免卡顿。
1. startTransition
jsx
import { startTransition } from "react";
const handleInputChange = (e) => {
startTransition(() => {
setSearchQuery(e.target.value);
});
};
(三)useDeferredValue
(降低 UI 更新优先级)
jsx
const deferredQuery = useDeferredValue(searchQuery);
React 会优先渲染 高优先级任务 (如输入框输入),而延迟更新 低优先级任务(如搜索结果)。
十、总结
1. 事件处理
- 事件使用 合成事件
- 可以通过
preventDefault
阻止默认行为 - 事件处理函数应使用
useCallback
进行优化
2. 状态管理
- 组件内部状态使用
useState
- 组件间状态共享可使用
Context API
- 大规模应用推荐
Redux
3. 性能优化
React.memo
避免组件重复渲染useMemo
缓存计算值useCallback
缓存事件处理函数
4. React 18 关键优化
- 自动批量更新
- 并发渲染
useDeferredValue
降低 UI 更新优先级