I have the code structured in the following manner, When I try loading useBlocker, It throws the following error Error: useBlocker must be used within a data router
. So inorder to fix this, we have to replace BrowserRouter with createBrowserRouter. How do I replace with the following structure.
index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import { Provider as ReduxProvider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<ReduxProvider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</ReduxProvider>
</React.StrictMode>
);
Function app component
import {Routes, Route} from "react-router-dom";
import About from "./component/About";
import Team from "./component/Team";
import Home from "./component/Home";
function App() {
return (
<>
<Navbar />
<Routes >
<Route path="/" element={ <Home /> } />
<Route path="/team" element={ <Team /> } />
<Route path="/about" element={ <About /> } />
</Routes>
</>
);
}
export default App;
How do we add createBrowserRouter
in this case where I want to have my routes inside my App.tsx
EDIT 2:
withRouter hook
import {
Location,
NavigateFunction,
Params,
useLocation,
useNavigate,
useParams,
} from "react-router-dom";
export interface RouterProps {
location: Location;
navigate: NavigateFunction;
params: Params;
}
export interface WithRouter {
router: RouterProps;
}
function withRouter(Component: any) {
function ComponentWithRouterProp(props: any) {
const location = useLocation();
const navigate = useNavigate();
const params = useParams();
return <Component {...props} router={{ location, navigate, params }} />;
}
return ComponentWithRouterProp;
}
export default withRouter;
class App extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
}
render() {
return (
<div className='container'>
<Navbar />
<Suspense>
<Routes>
<Route path="/" element={ <Home /> } />
<Route path="/team" element={ <Team /> } />
<Route path="/about" element={ <About /> } />
</Routes>
</Suspense>
</div>
);
}
}
export default withRouter(App);
It doesn't need to be declared in your index file, but it just needs to be declared/rendered higher in the ReactTree than any of the components that need to access the routing context it provides.
You can declare the router in the App
file. Create a layout route to render the Navbar
.
index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import { Provider as ReduxProvider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<ReduxProvider store={store}>
<App />
</ReduxProvider>
</React.StrictMode>
);
App.tsx
import {
createBrowserRouter,
createRoutesFromElements,
RouterProvider,
Route,
Outlet,
} from "react-router-dom";
import About from "./component/About";
import Team from "./component/Team";
import Home from "./component/Home";
const AppLayout = () => (
<>
<Navbar />
<Outlet />
</>
);
const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<AppLayout />}>
<Route path="/" element={<Home />} />
<Route path="/team" element={<Team />} />
<Route path="/about" element={<About />} />
</Route>
)
);
function App() {
return <RouterProvider router={router} />;
}
export default App;