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')
);
3
  • 2
    Can you share a more complete example? I'm guessing there's a router and Routes and Route components wrapping and rendering App? stackoverflow.com/help/minimal-reproducible-example Commented Mar 3, 2022 at 16:16
  • Updated to include contents of index js - showing the Routes Commented Mar 3, 2022 at 16:20
  • Have you considered firing useEffect conditionally ? Check this answer out: stackoverflow.com/a/62422674/2068732 Commented Jun 25, 2023 at 10:09

1 Answer 1

5

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

Sign up to request clarification or add additional context in comments.

2 Comments

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 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.