Custom NPM packages : useLocation() may be used only in the context of a <Router> component

25 Views Asked by At

I'm creating this post because after hours of searching I couldn't find the solution anywhere online so I'll be answering my own question with the solution in case somebody has the same issue as me.

The issue

I have a React app that uses react-router-dom for routing and navigating. I also have a separate custom NPM package which contains shared logic used across multiple apps of mine. In this shared package, I created a custom to perform some state updates when the URL search params are changed :

// This custom hook is in my shared NPM package
import { useSearchParams } from 'react-router-dom';

export function useCustomHookExample(): void {
  const [searchParams] = useSearchParams();
  useEffect(() => {
    // Do something with search params...
  }, [searchParams]);
}

When I used this hook in my own React app, I got the following error message :

Uncaught Error: useLocation() may be used only in the context of a <Router> component.

Apparently, this was thrown because useSearchParams used the useLocation hook internally, and this hook can only be called inside a Router context. And every time I tried to look for someone having this issue online, people just seemed to have forgotten to place a Router component higher up in the tree. But even after doing that I still get the same issue :

export function AppRouter() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path='/' element={<App />} />
      </Routes>
    </BrowserRouter>
  );
}

export function App() {
  // Still throws the error even though the hook was called within a Router context :(
  useCustomHookExample();
  ...
}
1

There are 1 best solutions below

0
souyahia On

The solution

So after hours of looking up online, I tried to take a look at the source code of the useLocation hook, and I saw the following comment :

// TODO: This error is probably because they somehow have 2 versions of the
// router loaded. We can help them understand how to avoid that.
`useLocation() may be used only in the context of a <Router> component.`

Basically this told me that my issue was coming from the fact that I had two versions of the react-router-dom package installed in my app : one for my custom NPM package, and one for my React app. To fix this, I simply put react-router-dom in the peer dependencies of my custom package, to make sure that the only installed version of this package is the one used be my app