Im new to react routers and currently using the BrowserRouter
from react-router-dom
with the version react-router-dom": "^6.21.0"
Im using the useLocation()
to dynmaically set a store variable whenever the path changes.
Here is what im doing:
App.tsx:
function App() {
const location = useLocation();
const setMode= useStore((state) => state.setMode);
useEffect(() => {
setMode(location.pathname.includes(Constants.AppRoutes.IMAGE_PATH));
}, [location.pathname, setMode]);
const routesBody = (
<div className="main">
<Comp1/>
<Comp2/>
<Comp3/>
</div>
);
const routes = [
{ path: "/", element: <Navigate replace to="bla1" /> },
{
path: "/bla1",
element: routesBody,
},
{
path: "/bla2",
element: routesBody,
},
];
return (
<BrowserRouter>
<Routes>
{routes.map((route) => (
<Route key={route.path} path={route.path} element={route.element} />
))}
</Routes>
</BrowserRouter>
);
}
export default App;
Main.tsx:
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
This setup causes the following error
Uncaught Error: useLocation() may be used only in the context of a <Router> component.
What I did:
Moving the <BrowserRouter>
tag from the app.tsx
to the main.tsx
to make the main.tsx
look like this:
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
);
While this seems to solve the issue and the routing works it causes all my test cases to have the following clause when rendering otherwise all the test cases will fail to render.
render(
<BrowserRouter>
<App />
</BrowserRouter>,
);
Why cant i just put the <BrowserRouter>
in my App.tsx?
Am i missing something?
2
Answers
Solved by using the solution found here
The code looks like this now:
useLocation
uses a React Context provided byBrowserRouter
. In order to be able to read from a Context, a component need have the Context provider (in this case,BrowserRouter
) as an ancestor of the React tree.As for your test cases, you could either
BrowserRouter
for you.App
containsBrowserRouter
: