Search code examples
reactjsreact-hooksreact-routerreact-router-domuse-effect

App useEffect not firing with react router


I am trying to add some analytics to my app. At the top level (within App.js) I have a fairly simple layout- a navbar, and outlet (for react router), and a footer. When navigating through the page, the outlet is updated to show my content- shouldn't this call the componentDidUpdate method? I am only seeing my useEffect hook fire after the first render.

If this is operating as expected, is there a better location to place a hook that will be called as a user navigates the page?

(partial) contents of app.js:

function App() {

  useEffect(() => {
    console.log(window.location.pathname)
  })

  return (
    <div className="App">
      <ThemeProvider theme={theme}>
        <Navbar />
        <Outlet />
        <Footer />
      </ThemeProvider>
    </div>
  );
}

index.js:

ReactDOM.render(
  <React.StrictMode>
    <SimpleReactLightbox>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<App />}>
            <Route path="/" element={<Landing />} />
            <Route path="/portfolio" element={<PortfolioGrid />} />
            <Route path="/portfolio" element={<Portfolio />}>
              <Route path=":portfolioId" element={<Portfolio />} />
            </Route>
            <Route path="/aboutme" element={<AboutMe />} />
            <Route path="/downloads" element={<Downloads />}>
              <Route index element={<DefaultDownload />} />  
              <Route path=":downloadId" element={<MyDownloads />} />
            </Route>
          </Route>
        </Routes>
      </BrowserRouter>
    </SimpleReactLightbox>
  </React.StrictMode>,
  document.getElementById('root')
);

Solution

  • I don't immediately know why using no dependency and logging the window.location object doesn't work, but using the currently matched location object appears to work. Use the useLocation hook and add location as the useEffect hook's dependency.

    Example:

    import { Outlet, useLocation } from "react-router-dom";
    
    function App() {
      const location = useLocation();
    
      useEffect(() => {
        console.log(location.pathname);
      }, [location]);
    
      return (
        <div className="App">
          <ThemeProvider theme={theme}>
            <Navbar />
            <Outlet />
            <Footer />
          </ThemeProvider>
        </div>
      );
    }
    

    Edit app-useeffect-not-firing-with-react-router