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:
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;
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.
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?
Solved by using the solution found here
The code looks like this now:
const AppLayout = () => {
const location = useLocation();
useEffect(() => {
//do stuff with the location.
}, [location]);
return (
<div>
<Comp1/>
<Comp2/>
<Comp3/>
</div>
);
};
const router = createBrowserRouter(
createRoutesFromElements(
<>
<Route path="/" element={<Navigate replace to="/bla1"/>} />
<Route path="/bla1" element={<AppLayout />} />
<Route path="/bla2" element={<AppLayout />} />
</>
)
);
function App() {
return <RouterProvider router={router} />;
}