在 React 中,“防止重复渲染(不必要的重新渲染)”是性能优化的核心问题。下面从原理 → 常用手段 → 实战建议系统讲一下。
React 默认策略:
父组件渲染 → 所有子组件都会重新渲染(不管 props 是否变化)
React.memo(函数组件)避免props 没变却重新渲染
const Child = React.memo(function Child({ value }) {
return <div>{value}</div>;
});
✅ 适用于:
⚠️ 注意:
useMemo:缓存计算结果避免重复计算 + 重复生成对象
const data = useMemo(() => heavyCompute(props), [props]);
也可用于稳定 props:
const style = useMemo(() => ({ color: 'red' }), []);
useCallback:缓存函数引用防止函数 props 变化导致子组件渲染
const handleClick = useCallback(() => {
console.log('click');
}, []);
配合 React.memo 使用效果最好:
<Child onClick={handleClick} />
❌ 错误示例(一个 state 影响整个组件):
function Page() {
const [count, setCount] = useState(0);
return (
<>
<ExpensiveComponent />
<button onClick={() => setCount(c => c + 1)}>{count}</button>
</>
);
}
✅ 优化:
function Page() {
const [count, setCount] = useState(0);
return (
<>
<Expensive />
<Counter count={count} setCount={setCount} />
</>
);
}
// ❌ 全局 state
function App() {
const [open, setOpen] = useState(false);
}
// ✅ 局部 state
function Modal() {
const [open, setOpen] = useState(false);
}
key 控制重建而不是更新{isEdit ? <Form key="edit" /> : <Form key="create" />}
✅ 用于:
❌ 错误用法(一个小变化全量刷新):
<Context.Provider value={{ user, theme }}>
✅ 拆分 Context:
<UserContext.Provider value={user}>
<ThemeContext.Provider value={theme}>
或使用 useMemo:
const value = useMemo(() => ({ user, theme }), [user, theme]);
{list.map(item => (
<ListItem key={item.id} item={item} />
))}
✅ 给稳定 key
✅ ListItem 用 React.memo
class Child extends React.PureComponent {}
等价于 React.memo
❌ 不要过早优化
❌ 不要为了少渲染写复杂代码
✅ 先保证正确,再优化慢的地方
why-did-you-renderReact 防止重复渲染的核心:
减少 state 影响范围 + 稳定 props 引用 + 合理使用 memo / useMemo / useCallback
如果你愿意,可以贴一段你的 React 代码,我可以直接帮你指出“哪里在重复渲染、怎么改”。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。