We are trying to migrate RouterProvider to use Data API (ScrollRestoration) in react router dom v6.
It is challenging to handle parallel Routes
which render two different components under the same path.
I checked and tweaked many examples of single Routes
and nested Routes
. None of my tries didn't work.
It is hard to find examples similar to this case. How would you migrate to RouterProvider for the following code? The following is the code I am trying to migrate.
App.tsx
function App() {
return (
<div className="app">
<TopNav />
<div className="title">
<Routes>
<Route path="/support" element={<></>} />
<Route path="/" element={<Title />} />
<Route path="/:categoryId" element={<Title />} />
<Route path="/:categoryId/:subcategoryId" element={<Title />} />
<Route path="/:categoryId/:subcategoryId/:contentId" element={<Title />} />
</Routes>
</div>
<SideNav />
<div className="content">
<div className="page-section">
<main>
<Routes>
<Route path="/support" element={<Form />} />
<Route path="/" element={<Content />} />
<Route path="/:categoryId" element={<Content />} />
<Route path="/:categoryId/:subcategoryId" element={<Content />} />
<Route path="/:categoryId/:subcategoryId/:contentId" element={<Content />} />
</Routes>
</main>
<Footer />
</div>
</div>
</div>
);
}
index.tsx
ReactDOM.render(
<React.StrictMode>
<PrismicProvider client={client}>
<BrowserRouter>
<App />
</BrowserRouter>
</PrismicProvider>
</React.StrictMode>,
document.getElementById('root')
);
This is how I managed to migrate to RouterProvider
from BrowserRouter
.
Refactor the code is necessary to remove some repetitions.
I created RootLayout
, TitleLayout
, and ContentLayout
.
Then, I wrapped Title
component with TitleLayout
. It goes the same way for the Content
component.
App.tsx
import { RouterProvider, createBrowserRouter, Outlet, ScrollRestoration } from 'react-router-dom';
import TopNav from './components';
import Hero from './components';
import SideNav from './components';
import Footer from './components';
import ContentPage from './components';
import FormPage from './components';
export const router = createBrowserRouter([
{
element: <RootLayout />,
children: [
{
path: '/support',
element: (
<>
<TitleLayout>
<></>
</TitleLayout>
<ContentLayout>
<FormPage />
</ContentLayout>
</>
),
},
{
path: '/',
element: (
<>
<TitleLayout>
<Hero />
</TitleLayout>
<ContentLayout>
<ContentPage />
</ContentLayout>
</>
),
},
{
path: '/:categoryId',
element: (
<>
<TitleLayout>
<Hero />
</TitleLayout>
<ContentLayout>
<ContentPage />
</ContentLayout>
</>
),
},
{
path: '/:categoryId/:subcategoryId',
element: (
<>
<TitleLayout>
<Hero />
</TitleLayout>
<ContentLayout>
<ContentPage />
</ContentLayout>
</>
),
},
{
path: '/:categoryId/:subcategoryId/:contentId',
element: (
<>
<TitleLayout>
<Hero />
</TitleLayout>
<ContentLayout>
<ContentPage />
</ContentLayout>
</>
),
},
],
},
]);
function RootLayout() {
return (
<div className="app">
<TopNavigation />
<Outlet />
<ScrollRestoration />
</div>
);
}
function TitleLayout({ children }: { children: React.ReactNode }) {
return (
<>
<div className="title">{children}</div>
<SideNavigation />
</>
);
}
function ContentLayout({ children }: { children: React.ReactNode }) {
return (
<>
<div className="content">
<div className="page-area">
<main className="page-content">{children}</main>
<Footer />
</div>
</div>
</>
);
}
function App() {
return <RouterProvider router={router} />;
}
export default App;
index.tsx
ReactDOM.render(
<React.StrictMode>
<PrismicProvider client={client}>
<App />
</PrismicProvider>
</React.StrictMode>,
document.getElementById('root')
);