如何修复React严格模式下空依赖useEffect中setState调用两次的问题?
解决React StrictMode下useEffect执行两次导致状态异常的问题
问题原因
React 18的StrictMode在开发环境中会刻意重复执行副作用(如useEffect)、组件挂载/卸载逻辑,目的是帮开发者提前发现未清理的副作用或不符合预期的重复执行代码。你的代码里,空依赖数组的useEffect被执行了两次,每次都调用setCount(prev => prev+1),最终count从0变成2。
解决方案
方案1:用useRef标记副作用是否已执行
通过useRef存储一个标记,确保副作用只执行一次:
const { createRoot } = ReactDOM; const { StrictMode, useEffect, useState, useRef } = React; function Test() { const [count, setCount] = useState(0); const hasInitialized = useRef(false); useEffect(() => { if (!hasInitialized.current) { setCount(prev => prev + 1); hasInitialized.current = true; } }, []); return <h1>Count: {count}</h1>; } const root = createRoot(document.getElementById("root")); root.render(<StrictMode><Test /></StrictMode>);
useRef的current属性在组件生命周期内保持引用且不会触发重渲染,适合用来做执行标记。
方案2:直接在useState中设置初始值
如果只是初始化状态,完全不需要依赖useEffect,直接在useState里设置初始值更简洁:
function Test() { // 直接将初始值设为1,替代useEffect的初始化操作 const [count, setCount] = useState(1); return <h1>Count: {count}</h1>; }
方案3:临时移除StrictMode(不推荐)
如果只是临时测试想让开发环境和生产环境行为一致,可以去掉StrictMode的包裹,但不建议长期这么做——StrictMode能帮你提前发现很多潜在问题:
root.render(<Test />);
内容的提问来源于stack exchange,提问作者Wing
相关产品推荐
相关产品推荐

