性能优化
shouldComponentUpdate
通过返回布尔值控制组件是否更新:
javascript
shouldComponentUpdate(nextProps, nextState) {
return nextState.number % 2 === 0; // 偶数才更新
}PureComponent
自动进行浅比较,避免不必要的渲染:
javascript
class PureComp extends React.PureComponent {
render() {
return <div>{this.props.value}</div>;
}
}React.memo
用于函数组件的记忆化:
javascript
const MemoCounter = React.memo(Counter);
// 自定义比较函数
const MemoComp = React.memo(Comp, (prevProps, nextProps) => {
return prevProps.value === nextProps.value;
});性能优化最佳实践
javascript
function App() {
const [username, setUsername] = useState("zhufeng");
const [count, setCount] = useState(0);
// 缓存对象
const displayData = useMemo(() => ({ count }), [count]);
// 缓存回调函数
const incrementCount = useCallback(() => {
setCount((count) => count + 1);
}, []);
return (
<div>
<input value={username} onChange={(e) => setUsername(e.target.value)} />
<MemoChildButton
displayData={displayData}
incrementCount={incrementCount}
/>
</div>
);
}重要概念
合成事件 (SyntheticEvent)
React 实现的事件系统,与原生事件隔离,跨浏览器兼容。
批量更新 (Batching)
React 会将多个状态更新合并为一次渲染,提高性能。
受控组件与非受控组件
- 受控组件:表单元素的值由 React state 控制
- 非受控组件:表单元素的值由 DOM 自身控制
组件通信方式
- Props - 父子组件通信
- Callback - 子父组件通信
- Context - 跨层级通信
- Redux/Zustand - 全局状态管理
- Event Bus - 兄弟组件通信
- Ref - 直接访问子组件实例
性能优化(续)
17.1 React.memo 和 useMemo
React.memo 用于防止不必要的组件重新渲染:
javascript
// 仅当 props 变化时才重新渲染
const Button = React.memo(({ onClick, label }) => {
console.log("Button rendered");
return <button onClick={onClick}>{label}</button>;
});useMemo 缓存计算结果:
javascript
const ExpensiveComponent = ({ items }) => {
// 只有当 items 变化时才重新计算
const sortedItems = useMemo(() => {
console.log("Sorting items...");
return [...items].sort((a, b) => a - b);
}, [items]);
return (
<div>
{sortedItems.map((item) => (
<p key={item}>{item}</p>
))}
</div>
);
};17.2 useCallback
缓存函数引用,防止子组件不必要的重新渲染:
javascript
const Parent = () => {
const [count, setCount] = useState(0);
// 只有当依赖项变化时,函数引用才会改变
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return <Child onClick={handleClick} />;
};17.3 代码分割和懒加载
javascript
import { lazy, Suspense } from "react";
const HeavyComponent = lazy(() => import("./HeavyComponent"));
export default function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</Suspense>
);
}17.4 虚拟列表
对于长列表,使用虚拟滚动提高性能:
javascript
// 使用库如 react-window 或 react-virtualized
import { FixedSizeList } from "react-window";
const Row = ({ index, style }) => <div style={style}>Item {index}</div>;
export default function VirtualList() {
return (
<FixedSizeList height={600} itemCount={10000} itemSize={35} width="100%">
{Row}
</FixedSizeList>
);
}