主题
React 严格模式下组件渲染两次的原因及解决方案
更新: 9/4/2025字数: 0 字 时长: 0 分钟
一、为什么严格模式会导致组件渲染两次?
在 React 的严格模式(Strict Mode)下,组件会故意渲染两次,这是 React 团队特意设计的行为,目的是帮助开发者发现潜在的问题。
主要原因
检测副作用问题:
React通过故意重复调用以下方法来识别不纯的代码:- 组件函数体
render方法setState更新函数useState、useMemo和useReducer的初始化函数
准备并发模式:帮助开发者提前发现可能在并发渲染中出现的问题
识别不安全的生命周期:帮助发现将被废弃的生命周期方法的使用
二、哪些情况会触发双渲染?
严格模式下的双渲染行为主要发生在开发环境中,生产环境不会出现这种情况。
具体触发场景
组件挂载阶段:
jsxfunction MyComponent() { console.log("渲染"); // 开发环境下会打印两次 return <div>Hello</div>; }状态更新时:
jsxconst [count, setCount] = useState(0); // setCount() 调用时相关逻辑也会执行两次Effect 清理和设置:
jsxuseEffect(() => { console.log("Effect运行"); // 开发环境下会打印两次 return () => console.log("清理"); // 也会立即执行清理 }, []);
三、为什么这是有价值的?
虽然双渲染看起来像是个"bug",但它实际上帮助开发者发现了很多潜在问题:
识别不纯的计算:
jsxlet globalIndex = 0; function UnpureComponent() { globalIndex++; // 严格模式下会发现这个副作用问题 return <div>{globalIndex}</div>; }发现 Effect 问题:
jsxuseEffect(() => { socket.connect(); // 严格模式下会立即调用清理函数,暴露忘记清理的问题 }, []);准备并发特性:帮助组件适应未来可能中断和恢复的渲染过程
四、如何应对双渲染?
1. 编写纯组件
确保组件渲染没有副作用:
jsx
// ✅ 纯函数组件
function PureComponent({ data }) {
const computedValue = useMemo(() => expensiveCalculation(data), [data]);
return <div>{computedValue}</div>;
}2. 正确处理 Effects
使用清理函数保持幂等性:
jsx
useEffect(() => {
const timer = setInterval(() => {}, 1000);
return () => clearInterval(timer); // 正确清理
}, []);3. 使用 useMemo/useCallback 优化
避免不必要的昂贵计算:
jsx
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);4. 生产环境验证
记住双渲染只发生在开发环境,生产环境不会出现:
jsx
if (process.env.NODE_ENV === "production") {
// 生产环境特定逻辑
}五、什么时候应该禁用严格模式?
大多数情况下不应该禁用严格模式,但在某些特殊场景可以考虑:
- 性能敏感的演示/基准测试
- 与某些不兼容严格模式的第三方库一起使用时
禁用方法(不推荐):
jsx
// 移除或注释掉 StrictMode
ReactDOM.render(
// <React.StrictMode>
<App />
// </React.StrictMode>,
document.getElementById('root')
);