Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

You should call navigate() in a React.useEffect(), not when your component is first rendered. (React+ReactROuterDom v6)

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>
      )
    }
like image 517
Simmi George Avatar asked Jan 01 '26 01:01

Simmi George


1 Answers

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>
  );
};
like image 185
Amit Avatar answered Jan 05 '26 19:01

Amit



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!