There's a reason for the eslint error and that's to prevent hard to notice bugs due to stale values. Essentially the lint error is just telling you that your userInterface variable is going to be stale within the effect.
It isn't necessarily a good idea to mute that error because then if you add more dependencies you might not realize why things aren't updating like you expect.
Another post about the same thing:
useEffect dependency array and ESLint exhaustive-deps rule
https://github.com/facebook/create-react-app/issues/6880
One major thing you should keep in mind is making sure you clean-up your actions regardless of if it's only being done on mount, because sometimes the effects can live beyond the life of the component if you don't clean it up.
You have several different options for how to fix this, if dispatch is stable (which based on the name, it usually is), then you can pull dispatch off of the userInterface variable and then add it to the dependency array.
const { dispatch } = userInterface;
useEffect(() => {
const handleRouteChangeComplete = () => {
window.scrollTo(0, 0);
dispatch(closeNavigation());
};
Router.events.on('routeChangeComplete', handleRouteChangeComplete);
() => {
Router.events.off('routeChangeComplete', handleRouteChangeComplete);
};
}, [dispatch]);
If pulling out the dispatch value isn't an option, then you can use a ref to make sure you keep the latest version of userInterface in a stable manner. This is a common enough task at times that you might want to extract the logic to a custom hook to get a ref of a value.
const userInterfaceRef = useRef(userInterface);
useEffect(() => {
userInterfaceRef.current = userInterface;
}, [userInterface]);
useEffect(() => {
const handleRouteChangeComplete = () => {
window.scrollTo(0, 0);
userInterfaceRef.current.dispatch(closeNavigation());
};
Router.events.on('routeChangeComplete', handleRouteChangeComplete);
() => {
Router.events.off('routeChangeComplete', handleRouteChangeComplete);
};
}, []);
The reason for the seemingly extra useEffect here is because unless you know for sure that the userInterface will never change, then you need to keep it up to date or else the userInterfaceRef will be stale. The reason I made the ref of userInterface instead of the dispatch function is because this way you can use other properties of the userInterface within the effect without any issues.
If you need to have dependencies in your effect that you don't want to restart the effect, use the ref option I described to ensure you have the latest value without the need for re-running the effect every time they change.
If you are adding an on handler to something imperatively in an effect, you should make sure to clean it up. It's a good habit to get into.