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();
...
}
The solution
So after hours of looking up online, I tried to take a look at the source code of the
useLocationhook, and I saw the following comment :Basically this told me that my issue was coming from the fact that I had two versions of the
react-router-dompackage installed in my app : one for my custom NPM package, and one for my React app. To fix this, I simply putreact-router-domin 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