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