Home > Software engineering >  You should call navigate() in a React.useEffect(), not when your component is first rendered. (React
You should call navigate() in a React.useEffect(), not when your component is first rendered. (React

Time:05-12

So this might be hard to get at first but I'll try to explain everything possible. I'm rendering an App component which uses useNavigation hook from react-router-dom library. Inside AppRoutes I check, if I have $stateParams.redirect and also other values like param1 and param2.I get $stateParams from another custom hook defined in my app. While running the app, I get the log, should navigate now but it actually doesn't navigate to decider-route page instead it stays at / which is <Home /> component. Also I have this warning in console You should call navigate() in a React.useEffect(), not when your component is first rendered. I was wondering why doesn't the navigation takes place to decider-route and the warning is the reason why navigation does not take place?

    const App = () => {
        return (
        <MemoryRouter>
          <AppRoutes />
        </MemoryRouter>
      )
    }
    
    const AppRoutes = () => {
      const navigate = useNavigate()                // react-router-dom v6
    
      if ($stateParams.redirect) {
        if ($stateParams.param1 && $stateParams.param2) {
          console.log('StateParams : ', $stateParams)
          console.log('Should navigate now!')
          navigate(`/decider-route/${$stateParams.param1}/${$stateParams.param2}`)
        }
      }
    
      return (
        <Routes>
          <Route path="/" element={<Home />} />
          <Route
            path="/decider-route/:param1/:param2"
            element={<Component />}
          />
        </Routes>
      )
    }

CodePudding user response:

The error is preety much self-explanatory. You just need to wrap the navigate() in a useEffect() hook so that it gets executed after the component mounts.

But, in this case, it is being called as soon as the component is first rendered.

navigate() should be triggered by a user action or an useEffect hook in this case. But you're not playing by the rules :)

app.js

const App = () => {
  return (
    <MemoryRouter>
      <AppRoutes />
    </MemoryRouter>
  );
};

const AppRoutes = () => {
  const navigate = useNavigate(); // react-router-dom v6

  useEffect(() => {
    if ($stateParams.redirect) {
      if ($stateParams.param1 && $stateParams.param2) {
        console.log("StateParams : ", $stateParams);
        console.log("Should navigate now!");
        navigate(
          `/decider-route/${$stateParams.param1}/${$stateParams.param2}`
        );
      }
    }
  }, []);

  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/decider-route/:param1/:param2 " element={<Component />} />
    </Routes>
  );
};
  • Related