如何解决React useEffect内调用函数时ESLint报依赖缺失警告问题
你遇到的是react-hooks/exhaustive-depsESLint规则的校验警告,该规则要求useEffect的依赖数组必须包含所有在effect内部使用到的外部变量,避免因闭包过时、依赖遗漏导致的逻辑异常。
下面是不同场景的最优解决方案:
通用解法(适用于所有同类场景)
首先要明确:自定义hooks返回的Setter方法、React Query返回的refetch这类生态库提供的方法,默认都是引用稳定的,不会随组件重渲染发生变化。你只需要把用到的方法加到依赖数组里即可,不会导致effect重复执行,完全能满足你仅在组件挂载时执行一次的需求。
第一个示例修改后代码:
const { error: { setErrorHolder }, } = useNotification(); useEffect(() => { if (process.env.NODE_ENV === "production") { setErrorHolder({ statusCode: 404, isAppError: true }); } }, [setErrorHolder]);
第二个示例修改后代码:
const { refetch } = useQuery('example'); useEffect(() => { refetch(); }, [refetch]);
React Query场景专属优化方案
你的第二个示例写法本身是冗余的:useQuery默认在组件挂载时就会自动发起请求,不需要手动包一层useEffect调用refetch,直接删除对应的useEffect代码即可,不会影响功能,也不会产生警告。
只有当你给useQuery设置了enabled: false(默认值为true),需要手动控制请求触发时机时,才需要调用refetch,这种情况用上面的通用解法添加依赖即可。
极端场景兼容方案
如果确实存在特殊逻辑,不需要将对应变量加到依赖数组,且你可以确认不会产生逻辑异常,可以通过注释单行禁用该规则,注意必须标注禁用原因,方便后续维护:
useEffect(() => { if (process.env.NODE_ENV === "production") { setErrorHolder({ statusCode: 404, isAppError: true }); } // 此处省略setErrorHolder依赖:该函数引用稳定,仅需挂载执行一次 // eslint-disable-next-line react-hooks/exhaustive-deps }, []);
注:该方案不推荐作为常规解法使用,极易因依赖遗漏导致隐藏bug。
扩展说明
如果是你在组件内部定义的普通函数需要放到effect里执行,用useCallback包裹该函数保证引用稳定后,再添加到useEffect的依赖数组即可解决同类警告。
内容的提问来源于stack exchange,提问作者Riky Andreas
相关产品推荐
相关产品推荐

