React useEffect缺依赖警告可否忽略及自定义Hook console.log重复打印问题
问题1:忽略useEffect缺失依赖警告是否可行
不建议无前提直接忽略警告,你可以结合业务场景判断,或是用更稳妥的方案规避警告:
- 如果你100%确定
itemName和initialValue在Hook的整个生命周期中永远不会变更(就像你当前调用时传入的是固定字面量"ITEMS_v1"和[]),可以直接在依赖数组上方加注释// eslint-disable-next-line react-hooks/exhaustive-deps屏蔽警告,不会出现业务问题。 - 如果你需要
itemName变更时重新执行effect读取本地存储,可以用useRef包裹initialValue规避依赖检测:
function useLocalStorage(itemName, initialValue) { const [item, setItem] = React.useState(initialValue); // 用ref存储initialValue,永远取最新的初始值同时不会触发effect更新 const initialValueRef = React.useRef(initialValue); React.useEffect(() => { const localStorageItem = localStorage.getItem(itemName); let parsedItem; if (!localStorageItem) { localStorage.setItem(itemName, JSON.stringify(initialValueRef.current)); parsedItem = initialValueRef.current; } else { parsedItem = JSON.parse(localStorageItem); } setItem(parsedItem); }, [itemName]); // 仅依赖itemName,不会再报initialValue的警告 console.log("This prints 2 times"); return { item }; }
如果直接忽略警告,后续如果修改代码让itemName或initialValue变成动态可变的参数,effect不会触发更新,会出现读取本地存储错误的隐蔽bug。
问题2:console.log打印两次的原因
有两层原因共同导致:
- Hook执行流程本身的两次渲染:
第一次是自定义Hook初始化执行,useState返回初始值,同步执行console.log触发第一次打印;之后useEffect异步执行,调用setItem更新状态,状态变更会触发Hook所在的AppProvider组件重渲染,自定义Hook随之重新执行,触发第二次打印。 - React严格模式的额外校验(可选)
如果你的项目开启了React.StrictMode,React 18+的开发环境下会故意让组件/Hook重复执行一次,用来检测代码中是否存在不符合规范的副作用,这种情况生产环境不会复现。
内容的提问来源于stack exchange,提问作者Risker
相关产品推荐
相关产品推荐

