简体   繁体   中英

React warning - useEffect has a missing dependency

This is my component:

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]);

    ...
    ....
}

I'm seeing the following warning in the console

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

Adding initFoo in the array [fooContext, currentFoo] that is passed in useEffect gives me further warnings and doesn't seem to fix the previous one. Both fooContext and currentFoo are required as inputs in the array as the functionality in the useEffect hook needs to be triggered whenever one of these two change a value.

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

Any ideas how I can fix this? I've tried to search for similar cases this warning pops, but haven't found a similar example in here

In your component definition, every time it re-renders, you're re-creating the variable initFoo .

React hook linting isn't smart enough to figure out this case. It says "hey, I see you're creating a new object every time your component renders. However, you don't update your useEffect callback, which only is set once. So if your initFoo changes without your useEffect changing, then your useEffect could end up setting an old value of initFoo , causing bugs."

In your case, initFoo is the "same" every time. Moving initFoo outside of the component definition stops it from being re-created on every component render, so React hook linting sees that it can never change, so the useEffect callback could never become "stale" based on the value of initFoo changing.

Another option is to inline the use of initFoo :

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

Which may be inconvenient here if you need to duplicate the result in useEffect .

This is also a warning, not an error, which you can ignore if you prefer to keep the declaration inside the component body for some reason. You can disable any ESLint rule with comments, if you want to ignore this warning, put this line above your useEffect call:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM