React hook useEffect dependency array
Suppress the linter because it gives you a bad advice. React requires you to pass to the second argument the values which (and only which) changes must trigger an effect fire.
useEffect(() => {
animateSomething(ref, props.onAnimationComplete);
}, [props.foo]); // eslint-disable-line react-hooks/exhaustive-deps
It leads to the same result as the Ryan's solution.
I see no problems with violating this linter rule. In contrast to useCallback
and useMemo
, it won't lead to errors in common case. The content of the second argument is a high level logic.
You may even want to call an effect when an extraneous value changes:
useEffect(() => {
alert(`Hi ${props.name}, your score is changed`);
}, [props.score]);
I would recommend writing this as follows:
const previousFooRef = useRef(props.foo);
useEffect(() => {
if (previousFooRef.current !== props.foo) {
animateSomething(ref, props.onAnimationComplete);
previousFooRef.current = props.foo;
}
}, [props.foo, props.onAnimationComplete]);
You can't avoid the complexity of having a condition inside the effect, because without it you will run your animation on mount rather than just when props.foo
changes. The condition also allows you to avoid animating when things other than props.foo
change.
By including props.onAnimationComplete
in the dependencies array, you avoid disabling the lint rule which helps ensure that you don’t introduce future bugs related to missing dependencies.
Here's a working example: