javascriptreactjsreact-hooksreact-routerreact-router-dom

React Router useNavigate with a useEffect hook - proper way to use?


I'm new to React and trying to make a loading/greeting page that navigates on to the next after a few seconds of being shown. In React Router v6, we have the useNavigate() hook to allow you to control the navigation, and I am using this to successfully call the navigate function by setting a timeout in a useEffect() hook. However, the compiler is complaining that I have a missing dependency. I only want it to run once though, not whenever the navigate changes. What is the best way to do this?

Thanks!

import { useEffect } from "react";
import { useNavigate } from "react-router-dom";

function Greeting(props) {
  const navigate = useNavigate();
  useEffect(() => {
    setTimeout(() => navigate(props.nextPage), 3000);
  }, []);

  return (
    <div className="Greeting">
      <div>Hello World!</div>
    </div>
  );
}

export default Greeting;

Line 9:6: React Hook useEffect has a missing dependency: 'navigate'. Either include it or remove the dependency array react-hooks/exhaustive-deps


Solution

  • The useEffect hook is missing dependencies, both the navigate function and props.nextPage that are referenced in the callback. Add them to the dependency array. Don't forget to return a cleanup function in the case that the component unmounts prior to the timeout expiring on its own.

    useEffect(() => {
      const timerId = setTimeout(() => navigate(props.nextPage), 3000);
      return () => clearTimeout(timerId);
    }, [navigate, props.nextPage]);
    

    As a general rule you should follow all guidance from the linter. The react-hooks/exhaustive-deps rule is there to help you write better code. Don't disable the rule for that line unless you absolutely know what you are doing and what future consequences may arise if/when you ever update the callback logic and possibly change dependencies.