首页 > 解决方案 > React 警告 - useEffect 缺少依赖项

问题描述

这是我的组件:

const FooComponent = () => {
    const initFoo = {
        attrOne: '',
        attrTwo: '',
        attrThree: '',
    };
    const fooContext = useContext(FooContext);
    const { addFoo, hasFoo, currentFoo } = fooContext;
    const [foo, setFoo] = useState(initFoo);

    useEffect(() => {
        if (hasFoo) {
            setFoo(currentFoo);
        } else {
            setFoo(initFoo);    
        }
    }, [fooContext, currentFoo]);

    ...
    ....
}

我在控制台中看到以下警告

Line 21:8:  React Hook useEffect has a missing dependency: 'initFoo'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

添加initFoo在 useEffect 中传递的数组[fooContext, currentFoo]会给我更多警告,并且似乎无法修复前一个警告。fooContext 和 currentFoo 都需要作为数组中的输入,因为只要这两者之一更改值,就需要触发 useEffect 挂钩中的功能。

Line 5:11:  The 'initFoo' object makes the dependencies of useEffect Hook (at line 21) change on every render. To fix this, wrap the initialization of 'initFoo' in its own useMemo() Hook  react-hooks/exhaustive-deps

有什么想法可以解决这个问题吗?我试图搜索此警告弹出的类似案例,但在这里没有找到类似的示例

标签: javascriptreactjsreact-hooksuse-effect

解决方案


在您的组件定义中,每次重新渲染时,您都在重新创建变量initFoo.

React hook linting 不够聪明,无法弄清楚这种情况。它说“嘿,我看到你每次渲染组件时都在创建一个新对象。但是,你不会更新你的useEffect回调,它只设置一次。所以如果你的initFoo改变没有useEffect改变,那么你useEffect最终可能会设置的旧值initFoo,导致错误。”

在您的情况下,initFoo每次都是“相同的”。移出initFoo组件定义会阻止它在每个组件渲染时重新创建,因此 React 钩子 linting 认为它永远不会改变,因此useEffect回调永远不会根据initFoo改变的值变得“陈旧”。

另一种选择是内联使用initFoo

useState({ attrOne: '', ... });

如果您需要将结果复制到useEffect.

这也是一个警告,而不是错误,如果您出于某种原因希望将声明保留在组件主体中,则可以忽略它。您可以禁用任何带有注释的 ESLint 规则,如果您想忽略此警告,请将此行放在您的useEffect调用上方:

// eslint-disable-next-line react-hooks/exhaustive-deps

推荐阅读