I have a react page built with React and Next.js that looks like this.
import Head from 'next/head';
import { useEffect, useState } from 'react';
import Header from '../components/Header';
export default function Home() {
const ticksPerSecond = 10;
const [points, setPoints] = useState(10);
const [pointsPerSecond, setPointsPerSecond] = useState(2);
useEffect(() => {
setInterval(() => {
setPoints((points) => points + pointsPerSecond / ticksPerSecond);
}, 1000 / ticksPerSecond);
}, []);
return (
<>
<Header points={points} pointsPerSecond={pointsPerSecond} />
</>
);
}
This code works as intended. Every second, points
will increase by pointsPerSecond
, and the state will be updated 10 times a second (as determined by ticksPerSecond
).
My issue comes from eslint which warns me:
React Hook useEffect has a missing dependency: 'pointsPerSecond'. Either include it or remove the dependency array. You can also replace multiple useState variables with useReducer if 'setPoints' needs the current value of 'pointsPerSecond'.eslintreact-hooks/exhaustive-deps
Having read that warning, I have tried many different solutions to appease the eslint gods in the sky, but the best I can do it replace the warnings with different warnings. Specifically, I have tried the solutions from this question which looks like the same problem. However, none of those solutions suppress the warning.
I recommend adding pointsPerSecond
to the dependency array and then making sure to return a cleanup function from your effect to clear the existing interval. This assumes you want to stop any existing interval and start a new one whenever pointsPerSecond
changes. If you don't include pointsPerSecond
in the dependency array, you'll be working with a stale version of that dependency.
import Head from 'next/head';
import { useEffect, useState } from 'react';
import Header from '../components/Header';
const ticksPerSecond = 10;
export default function Home() {
const [points, setPoints] = useState(10);
const [pointsPerSecond, setPointsPerSecond] = useState(2);
useEffect(() => {
const interval = setInterval(() => {
setPoints((points) => points + pointsPerSecond / ticksPerSecond);
}, 1000 / ticksPerSecond);
return () => { clearInterval(interval) }
}, [pointsPerSecond]);
return (
<>
<Header points={points} pointsPerSecond={pointsPerSecond} />
</>
);
}
There are a couple reasons I almost always recommend against silencing linting errors for hook dependency arrays: