React Router - 6/17/2024
React Router enables client side routing
React Router is a standard library for routing in React applications. It enables navigation among different views or components in a React application, allowing developers to build single-page applications (SPAs) with navigation capabilities similar to traditional multi-page websites.
Client side routing allows your app to update the URL from a link click without making another request for another document from the server. Instead, your app can immediately render some new UI and make data requests with fetch to update the page with new information.
Setup
npm install react-router-dom
Adding a router
import {
Route,
createBrowserRouter,
RouterProvider,
createRoutesFromElements,
} from "react-router-dom";
const router = createBrowserRouter(
// [
// {
// path: "/",
// element: <HomePage />,
// },
// ]
createRoutesFromElements(<Route path="/" element={<HomePage />} />)
);
const App = () => {
return <RouterProvider router={router} />;
};
export default App;
An
import { Outlet } from "react-router-dom";
import Navbar from '../componets/Navbar'
const MainLayout = () => {
return (
<>
<Navbar/>
<Outlet/>
</Navbar>
);
};
Add different pages
import {
Route,
createBrowserRouter,
RouterProvider,
createRoutesFromElements,
} from "react-router-dom";
import Mainlayout from './layouts/MainLayout'
import HomePage from ',/pages/HomePage'
import JobsPage from ',/pages/JobsPage'
import JobPage from ',/pages/JobPage'
import NotFoundPage from ',/pages/NotFoundPage'
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<MainLayout/>}>
<Route index element ={<HomePage/>}>
<Route path = '/jobs' element ={<JobsPage/>}>
<Route path = '/jobs/:id' element ={<JobPage/>}>
<Route path = '*' element ={<NotFoundPage/>}>
</Route>
)
);
const App = () => {
return <RouterProvider router={router} />;
};
export default App;
Dynamic Segments
If a path segment starts with : then it becomes a “dynamic segment”. When the route matches the URL, the dynamic segment will be parsed from the URL and provided as params to other router APIs.
<Route
// this path will match URLs like
// - /teams/hotspur
// - /teams/real
path="/teams/:teamId"
// the matching param will be available to the loader
loader={({ params }) => {
console.log(params.teamId); // "hotspur"
}}
// and the action
action={({ params }) => {}}
element={<Team />}
/>;
// and the element through `useParams`
function Team() {
let params = useParams();
console.log(params.teamId); // "hotspur"
}
and
<Link to={`/jobs/${job.id}`} className="...">
Read More
</Link>
A
import { NavLink } from "react-router-dom";
<NavLink to="/jobs" className={({ isActive }) => (isActive ? "active" : "")}>
Messages
</NavLink>;
useParams
The useParams hook returns an object of key/value pairs of the dynamic params from the current URL that were matched by the
import { useParams } from "react-router-dom";
function JobPage() {
// Get the userId param from the URL.
const { userId } = useParams();
// ...
}
useLoaderData
This hook provides the value returned from your route loader.we
if we fetch data use useEffect coming from react like this in JobPage:
import { useParams, useEffect, useState } from "react-router-dom";
function JobPage() {
const { id } = useParams();
const [job, setJob] = useState(null);
useEffect(() => {
const fetchJOb = async () => {
try {
const res = await fetch(`/api/jobs/${id}`);
const data = await res.json();
setJob(data);
} catch (error) {
} finally {
}
};
fetchJob();
}, []);
// ...
}
And we can also use useLoaderData:
As the user navigates around the app, the loaders for the next matching branch of routes will be called in parallel and their data made available to components through useLoaderData.
// in JobePage
import { useParams, useLoaderData } from "react-router-dom";
const JobPage = () => {
const { id } = useParams();
const job = useLoaderData()
return <h1>{job.title}</h1>
};
const jobLoader = async ({ params }) => {
const res = await fetch(`/api/jobs/${params.id}`);
const data = await res.json();
return data;
};
export { JobaPage as default, jobLoader };
// in App
import JobPage,{jobLoader} from ',/pages/JobPage'
const router = createBrowserRouter(
// Each route can define a "loader" function to provide data to the route element before it renders.
createRoutesFromElements(
<Route path="/" element={<MainLayout/>}>
<Route index element ={<HomePage/>}>
<Route path = '/jobs' element ={<JobsPage/>}>
<Route path = '/jobs/:id' element ={<JobPage/>} loader = {jobLoader}>
<Route path = '*' element ={<NotFoundPage/>}>
</Route>
)
);
const App = () => {
return <RouterProvider router={router} />;
};
export default App;