How to fix missing dependency warning when using useEffect React Hook?

前端 未结 13 1798
无人及你
无人及你 2020-11-22 03:14

With React 16.8.6 (it was good on previous version 16.8.3), I get this error when I attempt to prevent an infinite loop on a fetch request

./src/components/Bu         


        
相关标签:
13条回答
  • 2020-11-22 03:24
    const [mount, setMount] = useState(false)
    const fetchBusinesses = () => { 
       //function defination
    }
    useEffect(() => {
       if(!mount) {
          setMount(true);
          fetchBusinesses();
       }
    },[fetchBusinesses]);
    

    This is solution is pretty simple and you don't need to override es-lint warnings. Just maintain a flag to check whether component is mounted or not.

    0 讨论(0)
  • 2020-11-22 03:24

    Just pass the function as the argument in the array of useEffect...

    useEffect(() => {
       functionName()
    }, [functionName])
    
    0 讨论(0)
  • 2020-11-22 03:28

    You can remove the 2nd argument type array [] but the fetchBusinesses() will also be called every update. You can add an IF statement into the fetchBusinesses() implementation if you like.

    React.useEffect(() => {
      fetchBusinesses();
    });
    

    The other one is to implement the fetchBusinesses() function outside your component. Just don't forget to pass any dependency arguments to your fetchBusinesses(dependency) call, if any.

    function fetchBusinesses (fetch) {
      return fetch("theURL", { method: "GET" })
        .then(res => normalizeResponseErrors(res))
        .then(res => res.json())
        .then(rcvdBusinesses => {
          // some stuff
        })
        .catch(err => {
          // some error handling
        });
    }
    
    function YourComponent (props) {
      const { fetch } = props;
    
      React.useEffect(() => {
        fetchBusinesses(fetch);
      }, [fetch]);
    
      // ...
    }
    
    0 讨论(0)
  • 2020-11-22 03:29

    just disable eslint for the next line;

    useEffect(() => {
       fetchBusinesses();
    // eslint-disable-next-line
    }, []);
    

    in this way you are using it just like a component did mount (called once)

    updated

    or

    const fetchBusinesses = useCallback(() => {
     // your logic in here
     }, [someDeps])
    
    useEffect(() => {
       fetchBusinesses();
    // no need to skip eslint warning
    }, [fetchBusinesses]); 
    

    fetchBusinesses will be called everytime someDeps will change

    0 讨论(0)
  • 2020-11-22 03:31

    The solution is also given by react, they advice you use useCallback which will return a memoize version of your function :

    The 'fetchBusinesses' function makes the dependencies of useEffect Hook (at line NN) change on every render. To fix this, wrap the 'fetchBusinesses' definition into its own useCallback() Hook react-hooks/exhaustive-deps

    useCallback is simple to use as it has the same signature as useEffect the difference is that useCallback returns a function. It would look like this :

     const fetchBusinesses = useCallback( () => {
            return fetch("theURL", {method: "GET"}
        )
        .then(() => { /* some stuff */ })
        .catch(() => { /* some error handling */ })
      }, [/* deps */])
      // We have a first effect thant uses fetchBusinesses
      useEffect(() => {
        // do things and then fetchBusinesses
        fetchBusinesses(); 
      }, [fetchBusinesses]);
       // We can have many effect thant uses fetchBusinesses
      useEffect(() => {
        // do other things and then fetchBusinesses
        fetchBusinesses();
      }, [fetchBusinesses]);
    
    0 讨论(0)
  • 2020-11-22 03:32

    Actually the warnings are very useful when you develop with hooks. but in some cases, it can needle you. especially when you do not need to listen for dependencies change.

    If you don't want to put fetchBusinesses inside the hook's dependencies, you can simply pass it as an argument to the hook's callback and set the main fetchBusinesses as the default value for it like this

    useEffect((fetchBusinesses = fetchBusinesses) => {
       fetchBusinesses();
    }, []);
    

    It's not best practice but it could be useful in some cases.

    Also as Shubnam wrote, you can add below code to tell ESLint to ignore the checking for your hook.

    // eslint-disable-next-line react-hooks/exhaustive-deps
    
    0 讨论(0)
提交回复
热议问题