Hello Everyone, React router v6 is out. I have been tinkering with it for a while and I love it. With everything updated and some new hooks to use with your application, I have decided to write this article to share my knowledge on it. Let's begin
Prerequisites
- React
- Javascript/Typescript
Now, let us begin. We will start by creating our React Application using vite. I will be using pnpm
but feel free to use yarn
or npm
.
Go to your terminal and run the following commands
$ pnpm create vite@latest
Follow the prompts and select Typescript. Install the dependencies and start the app
Now let us start by installing the React router library React Router
$ pnpm add react-router-dom
Let us create a page. Create a folder called pages
in scr
and called it HomePage.tsx
. Then paste the following
function HomePage() {
return (
<div>
<h1>Home Page</h1>
</div>
);
}
export default HomePage;
Now, on our App.tsx
We need to write the following
import './App.css'
import { createBrowserRouter,RouterProvider} from "react-router-dom";
import HomePage from "./pages/HomePage";
function App() {
const router = createBrowserRouter([
{
path: "/",
element: <HomePage/>
},
]);
return (
<RouterProvider router={router}/>
)
}
export default App
Now when someone visits our http://localhost:5173/
they will be greeted with this page.
Now, in your application. You May have an overall layout comprising a design that your want other pages to wrap around this. Let me show you how we can do it.
Create a folder called components
and add a file called layouts.component.tsx
import { OutLet } from `react-router-dom`;
function LayoutsComponent() {
return (
<div>
<h1>This is the overall layout</h1>
<Outlet/>
</div>
);
}
export default LayoutsComponent;
Let us create two pages UsersPage.tsx
and ProductsPage.tsx
. Now add some dummy data and we import them in our App.tsx
Now with this, we need to wrap our app with this layout.
In our App.tsx
page:
import './App.css'
import { createBrowserRouter,RouterProvider} from "react-router-dom";
import HomePage from "./pages/HomePage";
import LayoutsComponent from './components/layouts.component';
import UsersPage from './pages/UsersPage';
import ProductsPage from './pages/ProductsPage';
function App() {
const router = createBrowserRouter([
{
path: "/",
element: <HomePage/>,
},
{
element: <LayoutsComponent/>,
children: [
{
path: "/users",
element: <UsersPage/>,
},
{
path: "/products",
element: <ProductsPage/>,
},
],
}
]);
return (
<RouterProvider router={router}/>
)
}
export default App
From above, we have just passed the
<UsersPage/>
and<ProductsPage/>
as children to the<LayoutsComponent/>
page, now they will wrap inside.
Now, in the Layouts component, you might want to pass data to every child component that might be wrapping inside it. This might come in handy, for example when you are designing for responsive view and you want to pass data to its children to respond a certain way when the layout changes. To do this we will us a special hook called useOutletContext()
but before we do this, in the layout.component.tsx
let us pass some data to the children.
import { useEffect, useState } from "react";
import { Outlet } from "react-router-dom";
function LayoutsComponent() {
const [data,setData] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(json => setData(json))
},[])
return (
<div>
<h1>This is the overall layout</h1>
<Outlet context={[data]} />
</div>
);
}
export default LayoutsComponent;
From our example, we have just updated our application import and now the data will be used my the children here.
Now to consume the data in our children(UsersPage):
import { useOutletContext } from "react-router-dom";
function UsersPage() {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [ data ]= useOutletContext<[string[]]>();
return (
<div>
<h1>Users Page</h1>
<ul>
{data.map((item,index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default UsersPage;
Now let us spice things up. You may want to introduce a loader, such that before we view a user information, before we view navigate to the user's profile page. To do this we write the following
{
path: "/users",
element: <UsersPage/>,
children: [
{
path: ":id",
element: <UserProfile/>,
loader: async ({ params }) => {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${params.id}`);
const data = await response.json();
return data;
}
},
],
},
From this, you can choose to display the user data information
import { useLoaderData } from "react-router-dom";
function UserProfile() {
const data= useLoaderData();
return (
<div>
<h1>User Profile</h1>
<p>{data}</p>
</div>
);
}
export default UserProfile;
Feel free to check the original documentation Docs
Top comments (0)