2

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')
);
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • 2
    Can you share a more complete example? I'm guessing there's a router and `Routes` and `Route` components wrapping and rendering `App`? https://stackoverflow.com/help/minimal-reproducible-example – Drew Reese Mar 03 '22 at 16:16
  • Updated to include contents of index js - showing the Routes – witty-user-name Mar 03 '22 at 16:20
  • Have you considered firing useEffect conditionally ? Check this answer out: https://stackoverflow.com/a/62422674/2068732 – matdev Jun 25 '23 at 10:09

1 Answers1

4

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

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Thank you! This works for me. Its still very strange to me that it won't work without the dependency, but I'm still a beginner with react, so I'm sure its something I'm overlooking... – witty-user-name Mar 03 '22 at 16:33
  • @witty-user-name It could be that the `window` object isn't aware of anything the routing context from RRD is doing (*all it's doing is manipulating the address bar*), while using the `useLocation` hook to access the routing context *actually* triggers a rerender with the new context value being accessible. This is what I suspect at least. – Drew Reese Mar 03 '22 at 16:35