Uncaught TypeError: Cannot read properties of undefined (reading 'location')

Viewed 5204

I am getting this error message while accessing the location from useLocation() hook. Actually I am trying to add google analytics to my react app but I am getting this error message. Uncaught TypeError: Cannot read properties of undefined (reading 'location')

useGaTracker hook code:

import { useEffect, useState } from "react"
import { useLocation } from "react-router-dom"
import ReactGA from "react-ga"

const useGaTracker = () => {
  const location = useLocation()
  const [initialized, setInitialized] = useState(false)
  console.log(location)

    useEffect(() => {
      if (!window.location.href.includes("localhost")) {
        ReactGA.initialize(process.env.REACT_APP_GOOGLE_ANALYTICS_KEY)
        setInitialized(true)
      }
    }, [])

    useEffect(() => {
      if (initialized) {
        ReactGA.pageview(location.pathname + location.search)
      }
    }, [initialized, location])
}

export default useGaTracker

App.js code

import React, { Suspense } from "react"
import { BrowserRouter, Switch, Route } from "react-router-dom"
import "./App.css"
import { Helmet } from "react-helmet"

import { AuthProvider } from "./context/AuthContext"

// custom components
import SideBar from "./components/layouts/SideBar"
import Navbar from "./components/layouts/Navbar"
import Footer from "./components/layouts/Footer"
import useGaTracker from "./hooks/useGaTracker"

// lazy loading components
const Dashboard = React.lazy(() => import("./components/dashboard/Dashboard"))

const App = () => {
  useGaTracker()
  return (
    <BrowserRouter>
      <Helmet>
        <title>CODINGSPACE - Learn by Building Web and Mobile Apps</title>
      </Helmet>
      <AuthProvider>
        <div className="relative grid min-h-screen md:grid-cols-layout-tablet xl:grid-cols-layout-desktop grid-rows-layout-desktop md:gap-6">
          <Navbar />
          <SideBar />
          <Switch>
            <Suspense fallback={<div>Loading..</div>}>
              <Route exact path="/" component={Dashboard} />
            </Suspense>
          </Switch>
          <Feedback />
          <Footer />
        </div>
      </AuthProvider>
    </BrowserRouter>
  )
}

export default App

enter image description here Anyone please help me with this

1 Answers

The useGaTracker hook is being used outside the BrowserRouter so there is no routing context above it in the ReactTree.

To Resolve, move the router to the component rendering App so there's a provided routing context. This may likely be the index.js file. (You'd typically wrap app with the AuthProvider here as well)

Example:

... other imports ...
import { BrowserRouter as Router } from 'react-router-dom';
import { AuthProvider } from "./context/AuthContext"

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <AuthProvider>
      <Router>
        <App />
      </Router>
    </AuthProvider>
  </StrictMode>,
  rootElement
);

...

const App = () => {
  useGaTracker(); // <-- has a routing context now!

  return (
    <>
      <Helmet>
        <title>CODINGSPACE - Learn by Building Web and Mobile Apps</title>
      </Helmet>
      <div className="relative grid min-h-screen md:grid-cols-layout-tablet xl:grid-cols-layout-desktop grid-rows-layout-desktop md:gap-6">
        <Navbar />
        <SideBar />
        <Switch>
          <Suspense fallback={<div>Loading..</div>}>
            <Route exact path="/" component={Dashboard} />
          </Suspense>
        </Switch>
        <Feedback />
        <Footer />
      </div>
    </>
  )
}
Related