I'm getting the react-hooks/exhaustive-deps
warning on an element that calls a function passed via props(onCountdownEnd
) in the useEffect hook, that is used to direct the application flow on the countdown end:
function Countdown(props: { seconds: number; onCountdownEnd: () => void }) {
const [count, setCount] = useState(props.seconds);
useEffect(() => {
if (!count) props.onCountdownEnd();
const intervalId = setInterval(() => {
setCount(count - 1);
}, 1000);
return () => clearInterval(intervalId);
}, [count]);
return <span className="text-xxl">00:0{count}</span>;
}
React Hook useEffect has a missing dependency: 'props'.
What is the correct way to approach this warning? I'm not sure I want to include props
in the dependancies array here.
Thanks!
CodePudding user response:
Don't include the props
object, since it changes on each render. You should destructure the props
, and include the exact dependency:
function Countdown({ seconds, onCountdownEnd }: { seconds: number; onCountdownEnd: () => void }) {
const [count, setCount] = useState(seconds);
useEffect(() => {
if (!count) onCountdownEnd();
const intervalId = setInterval(() => {
setCount(count - 1);
}, 1000);
return () => clearInterval(intervalId);
}, [count, onCountdownEnd]);
return <span className="text-xxl">00:0{count}</span>;
}
However, in your code the interval would be cleared and added on each change of count. You can refactor it to use the useState
updater function to avoid it, and handle onCountdownEnd
in another useEffect
block:
function Countdown({ seconds, onCountdownEnd }: { seconds: number; onCountdownEnd: () => void }) {
const [count, setCount] = useState(seconds);
useEffect(() => {
const intervalId = setInterval(() => {
setCount(current => current - 1);
}, 1000);
return () => clearInterval(intervalId);
}, []); // no dependencies
useEffect(() => {
if (!count) onCountdownEnd();
}, [count, onCountdownEnd]);
return <span className="text-xxl">00:0{count}</span>;
}
CodePudding user response:
when you use a function or a variable in useEffect
you have to pass them as dependencies array because the functionality of the callback is based on their value . sometimes you dont need to re-run useEffect
when they are changed so you can ignore the warning but in your case you can do this:
place this line of code before useEffect
const onCountdownEnd = {props}
and in your useEffect
if (!count) onCountdownEnd();
and finally pass onCountdownEnd
to the dependency array