Home > Software engineering >  React multiple useEffect with useCallback
React multiple useEffect with useCallback

Time:04-01

I'm struggling a bit with the use of useEffect and useCallback. My component consists of two input field, and two select elements.

For the two input fields, I have the following useEffect, which triggers a setTimeout after 500ms.

useEffect(() => {
    console.log('useEffect B');
    const timeout = setTimeout(() => console.log('test'), 500);
    return () => clearTimeout(timeout);
  }, [fromValue, toValue]);

For my two select fields, I have another simple useEffect

useEffect(() => {
    console.log('useEffect A');
  }, [fromSymbol, toSymbol]);

However, in both cases, I want to trigger another method, that does some calculations, so I figured, I can change my code to:

const calculateResult = useCallback(async () => {
    console.log('calculateResult');
    console.log(fromSymbol, toSymbol);
    console.log(fromValue, toValue);
  }, [fromSymbol, toSymbol, fromValue, toValue]);

  useEffect(() => {
    console.log('useEffect A');
    calculateResult();
  }, [fromSymbol, toSymbol, calculateResult]);

  useEffect(() => {
    console.log('useEffect B');
    const timeout = setTimeout(() => calculateResult(), 500);
    return () => clearTimeout(timeout);
  }, [fromValue, toValue, calculateResult]);

But now, whenever any value is changed, both useEffect A, and useEffect B are being triggered. I assume this is because calculateResult is a in the useEffect dependency list, but if I remove it, I get the following warning: React Hook useEffect has a missing dependency: 'calculateResult'. Either include it or remove the dependency array.

How do I solve this problem? For fromValue and toValue, I want to trigger this calculateResult directly, but for fromSymbol and toSymbol, I want to have a short delay.

CodePudding user response:

You are right useEffect A and useEffect B are both getting called because of calculateResult. So it was right decision to remove it from the dependency array and it is normal to get the warning from react.

React Hook useEffect has a missing dependency: 'calculateResult'. Either include it or remove the dependency array.

Now what you can do is add

eslint-disable-next-line 

in your useEffect to avoid the warnings. And it is normal to use it.

useEffect(() => {
  console.log('useEffect A');
  calculateResult();
  //eslint-disable-next-line
}, [fromSymbol, toSymbol]);

useEffect(() => {
  console.log('useEffect B');
  const timeout = setTimeout(() => calculateResult(), 500);
  return () => clearTimeout(timeout);
  //eslint-disable-next-line
}, [fromValue, toValue]);
  • Related