{"id":16159,"date":"2022-08-31T08:12:43","date_gmt":"2022-08-31T15:12:43","guid":{"rendered":"https:\/\/coderpad.io\/?p=16159"},"modified":"2023-06-05T14:12:12","modified_gmt":"2023-06-05T21:12:12","slug":"guide-to-react-router","status":"publish","type":"post","link":"https:\/\/coderpad.io\/blog\/development\/guide-to-react-router\/","title":{"rendered":"A Comprehensive Guide to React Router"},"content":{"rendered":"\n<p>Navigation routing in React is quite different from how it\u2019s done in web development using the HTML anchor tag. This is because React is used to build single-page applications\u2014meaning our application only loads once in our browser. This means we need a routing mechanism or logic to handle all forms of routing.<\/p>\n\n\n\n<p>In other JavaScript frameworks like Vue, this routing logic is built by the same team that works on the core framework, meaning that we don&#8217;t need an externally written package or dependency. In React, there is no official package to handle routing; instead, we depend on the most popular and standard library, React Router.<\/p>\n\n\n\n<p>React Router allows the browser URL to be changed and ensures the UI is in sync with the URL. It was built by <a href=\"https:\/\/twitter.com\/ryanflorence\" target=\"_blank\" rel=\"noopener\">Ryan Florence<\/a> and <a href=\"https:\/\/twitter.com\/mjackson\" target=\"_blank\" rel=\"noopener\">Michael Jackson<\/a>, who founded <a href=\"https:\/\/remix.run\/\" target=\"_blank\" rel=\"noopener\">Remix<\/a> to take React Router to the next level. They recently launched <a href=\"https:\/\/reactrouter.com\/\" target=\"_blank\" rel=\"noopener\">React Router version 6<\/a>, whose usage has grown massively over the past year with over <a href=\"https:\/\/www.npmjs.com\/package\/react-router-dom\" target=\"_blank\" rel=\"noopener\">8 million weekly downloads<\/a> at the time of writing. Today, React Router is maintained by <a href=\"https:\/\/remix.run\/\" target=\"_blank\" rel=\"noopener\">Remix<\/a> and <a href=\"https:\/\/github.com\/ReactTraining\/react-router\/graphs\/contributors\" target=\"_blank\" rel=\"noopener\">hundreds of other contributors<\/a>.<\/p>\n\n\n\n<p>This guide will teach you how to use React Router within your React project. We will learn how to implement React Router to ensure smooth routing within our single-page application. At the end of this guide, we will shed light on the future of React Router and how Remix plans to re-shape routing with React Router in future versions.<\/p>\n\n\n\n<p>In this article, we will learn how to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"#install-react-router\">Install React Router<\/a><\/li><li><a href=\"#set-up-and-access-browser-url\">Setup and Access Browser URLs<\/a><\/li><li><a href=\"#configure-and-create-routes\">Configure and Create Routes<\/a><\/li><li><a href=\"#access-configured-routes\">Access Configure Routes<\/a><\/li><li><a href=\"#handle-no-routes-without-matches\">Handle Routes without Matches<\/a><\/li><li><a href=\"#implement-nested-routes\">Implement Nested Routes<\/a><\/li><li><a href=\"#configure-parameter-enhanced-route\">Configure Parameter-Enhanced Routes<\/a><\/li><li><a href=\"#implement-programmatic-navigation\">Implement Programmatic Navigation<\/a><\/li><li><a href=\"#code-splitting-with-react-router\">Code Splitting with React Router<\/a><\/li><li><a href=\"#the-future-of-react-router\">The Future of React Router<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"install-react-router\">Install React Router<\/h2>\n\n\n\n<p>React Router is an external library that needs to be installed into our React application for us to use. We can do this by running either of the commands below in our terminal within our project&#8217;s directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Using npm<\/span>\n$ npm install react-router-dom@<span class=\"hljs-number\">6<\/span>\n\n<span class=\"hljs-comment\">\/\/ Or<\/span>\n\n<span class=\"hljs-comment\">\/\/ Using Yarn<\/span>\n$ yarn add react-router-dom@<span class=\"hljs-number\">6<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>When we install the React Router package within our project, we will have access to all its components and hooks; we can now use these hooks and components within our application to enable single-page routing.<\/p>\n\n\n\n<p>Once we have successfully installed this package, we can check our <code>package.json<\/code> file to confirm if it installed, and which version we have installed, within our <code>dependencies<\/code> object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-string\">\"dependencies\"<\/span>: {\n\u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ rest of the dependencies installed<\/span>\n\u00a0 \u00a0 <span class=\"hljs-string\">\"react-router-dom\"<\/span>: <span class=\"hljs-string\">\"^6.3.0\"<\/span>,\n\u00a0 },<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"set-up-and-access-browser-url\">Set Up and Access Browser URL<\/h2>\n\n\n\n<p>To use React Router within our application, we need to wrap the top-level component in our React applications component hierarchy, also known as the root component (<code>App.js<\/code>), with <code>BrowserRouter<\/code>.&nbsp;<\/p>\n\n\n\n<p><code>BrowserRouter<\/code> is a router implementation that uses the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/History_API\" target=\"_blank\" rel=\"noopener\">HTML5 History API<\/a>, which comprises the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/History\/pushState\" target=\"_blank\" rel=\"noopener\"><code>pushState<\/code><\/a><code>,<\/code><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/History\/replaceState\" target=\"_blank\" rel=\"noopener\"><code>replaceState<\/code><\/a><code>, and<\/code> <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Window\/popstate_event\" target=\"_blank\" rel=\"noopener\"><code>popstate<\/code><\/a> events. This History API helps track route history, keeping our UI in sync with the URL.<\/p>\n\n\n\n<p>To wrap our root component, we can do this in the <code>App.js<\/code> or <code>index.js<\/code> file. First, we would import <code>BrowserRouter<\/code> from <code>react-router-dom<\/code> in any of the components we wish to wrap. Let&#8217;s do this in our <code>index.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ index.js<\/span>\n<span class=\"hljs-comment\">\/\/ other imports<\/span>\n<span class=\"hljs-keyword\">import<\/span> { BrowserRouter } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> root = ReactDOM.createRoot(<span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'root'<\/span>));\nroot.render(\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">React.StrictMode<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">BrowserRouter<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">App<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">BrowserRouter<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">React.StrictMode<\/span>&gt;<\/span><\/span>\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If we want to do this in our <code>App.js<\/code> file, we just need to ensure that everything in our <code>App.js<\/code> file is wrapped with <code>&lt;BrowserRouter&gt;<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ App.js<\/span>\n<span class=\"hljs-keyword\">import<\/span> { BrowserRouter } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-router-dom\"<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">BrowserRouter<\/span>&gt;<\/span>\n      {\/* ... *\/}\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">BrowserRouter<\/span>&gt;<\/span><\/span>\n  );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"configure-and-create-routes\">Configure And Create Routes<\/h2>\n\n\n\n<p>We need to configure our routes to implement routing between components in our React application. Not all components will be a view (or rather, a page), so we need to declare which component is a view and assign a path to each.<\/p>\n\n\n\n<p>We do this with two major components, which are:&nbsp;<\/p>\n\n\n\n<p>&#8211; <a href=\"https:\/\/reactrouter.com\/docs\/en\/v6\/components\/routes\" target=\"_blank\" rel=\"noopener\"><code>Routes<\/code><\/a>: This is the parent component that wraps all our <code>configuredRoutecomponents. <\/code>This component is what React looks for when the location changes to access its children <code>&lt;Route&gt;<\/code> elements to find the best match and render that branch of the UI.<\/p>\n\n\n\n<p>&#8211; <a href=\"https:\/\/reactrouter.com\/docs\/en\/v6\/components\/route\" target=\"_blank\" rel=\"noopener\"><code>Route<\/code><\/a>: This is the component used to declare a specific location. It holds two props which are the path and element props. The path props hold the path we would use to access the specified element. The element can be a markup or a component.<\/p>\n\n\n\n<p>Suppose we have three components (Home, About, and Blog). Let&#8217;s configure routes for them in the <code>App.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ App.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { Routes, Route } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> Home <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/pages\/Home'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> About <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/pages\/About'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> Blog <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/pages\/Blog'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Home<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/about\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">About<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/blog\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Blog<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We first imported the two React Router components (<code>Routes<\/code> and <code>Route<\/code>) from <code>react-router-dom<\/code> in the above code. Then we import the components we would add to the <code>element<\/code> prop of each <code>Route<\/code> we configure.&nbsp;<\/p>\n\n\n\n<p>At this point, we can now navigate through our application via the URL. For example, if we navigate to <code>\/about<\/code>, the <code>About<\/code> component will show. If we navigate to <code>\/blog<\/code>, the <code>Blog<\/code> component will appear.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"access-configured-routes\">Access Configured Routes<\/h2>\n\n\n\n<p>In a real-world web application, we would not want users to navigate through routes via the URL, as that&#8217;s cumbersome to navigate. We have some components that make it easy to access these routes. Just like we have the anchor tag (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/a\" target=\"_blank\" rel=\"noopener\"><code>&lt;a&gt;<\/code><\/a>) in HTML5, we also have components like <a href=\"https:\/\/reactrouter.com\/docs\/en\/v6\/components\/link\" target=\"_blank\" rel=\"noopener\"><code>Link<\/code><\/a> in React Router, which we can use to access our routes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to Use The Link Component<\/h3>\n\n\n\n<p>To use the <code>Link<\/code> component, we first need to import it from <code>react-router-dom<\/code>. This component takes in an important prop, the <code>to<\/code> prop. The <code>to<\/code> prop is used to set the component we want our UI to load:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-comment\">&lt;!-- pages\/Home.js --&gt;<\/span>\n\nimport { Link } from 'react-router-dom';\n\nconst Home = () =&gt; {\n\u00a0 \u00a0 return (\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>Home Page<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Link<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">\"\/about\"<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"btn\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 About Page\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Link<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 );\n};\n\nexport default Home;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This works for all configured <code>path<\/code>s. We must ensure that the value passed into the <code>to<\/code> prop matches a configured <code>Route path<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Passing State Data Through Links<\/h3>\n\n\n\n<p>We can also pass state data via our <code>Link<\/code> component, which we can access in the component we navigate into with the <a href=\"https:\/\/reactrouter.com\/docs\/en\/v6\/hooks\/use-location\" target=\"_blank\" rel=\"noopener\"><code>useLocation()<\/code><\/a> router hook:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { Link } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n\n<span class=\"hljs-comment\">\/* ... *\/<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> userData = {\n\u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'John Doe'<\/span>,\n\u00a0 <span class=\"hljs-attr\">age<\/span>: <span class=\"hljs-number\">24<\/span>\n}\n\n<span class=\"hljs-comment\">\/* ... *\/<\/span>\n\n&lt;Link to=<span class=\"hljs-string\">\"\/profile\"<\/span> state={userData}&gt;Go to Profile&lt;<span class=\"hljs-regexp\">\/Link&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We can collect this data via the <code>useLocation()<\/code> hook:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { useLocation } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n\n<span class=\"hljs-comment\">\/*...*\/<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> location = useLocation();\n<span class=\"hljs-keyword\">const<\/span> stateData = location.state;\n<span class=\"hljs-built_in\">console<\/span>.log(stateData);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">How to Use The NavLink Component<\/h3>\n\n\n\n<p>In some situations, such as when creating a navbar, using the <code>Link<\/code> component is not the best approach to displaying links to other views. This is because, in some instances, we want a way to know which <code>Route<\/code> is active. For example, when we are navigated to the Home page, we would want the Home Link to be styled differently from others:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/08\/img_630e4bb0e2a79.png\" alt=\"\"\/><figcaption>Three links displayed: Home, About, and Blog. Home is underlined to indicate that it&#8217;s the current page.<\/figcaption><\/figure>\n\n\n\n<p>We can achieve this with the <code>NavLink<\/code> component. The <code>NavLink<\/code> component is a special kind of <code>Link<\/code> component with an <code>active<\/code> class by default when a particular link is active.&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ \/components\/Navbar.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { NavLink } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> Navbar = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"navbar\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">NavLink<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">\"\/\"<\/span>&gt;<\/span>Home<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">NavLink<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">NavLink<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">\"\/about\"<\/span>&gt;<\/span>About<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">NavLink<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">NavLink<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">\"\/blog\"<\/span>&gt;<\/span>Blog<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">NavLink<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">nav<\/span>&gt;<\/span><\/span>\n\u00a0 \u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Navbar;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We can use this <code>active<\/code> class to add styling in whichever way we prefer. For example, we can create a style for <code>active<\/code> in CSS this way:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-comment\">\/* index.css *\/<\/span>\n\n<span class=\"hljs-selector-class\">.navbar<\/span> <span class=\"hljs-selector-tag\">a<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-attribute\">text-decoration<\/span>: none;\n}\n<span class=\"hljs-selector-class\">.navbar<\/span> <span class=\"hljs-selector-tag\">a<\/span><span class=\"hljs-selector-class\">.active<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-number\">#333<\/span>;\n\u00a0 \u00a0 <span class=\"hljs-attribute\">text-decoration<\/span>: underline;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"handle-no-routes-without-matches\">Handle No Routes without Matches<\/h2>\n\n\n\n<p>At this point, we have learned how to configure a route and access the configured <code>Route<\/code>. The next big question that will pop into our minds is, &#8220;What happens when we navigate a route that is not configured?&#8221;<\/p>\n\n\n\n<p>The answer is nothing. Nothing happens. The path will match no route, meaning nothing will show on our screen. When we check our console, a warning error appears with the message <code>No routes matched location \"\/fff\"<\/code> because we tried routing to <code>\/fff<\/code>, which is not configured.<\/p>\n\n\n\n<p>We can fix this by setting up a no-match route, which will hold a component. Let&#8217;s set one up as a &#8220;not found&#8221; page or make a game out of missing pages, or more. This component will be displayed on our UI when a route does not match the configured <code>Route<\/code>. We can configure this no-match Route in the <code>&amp;lt;Routes&amp;gt;<\/code> configuration on our <code>App.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">&lt;!-- App.js --&gt;\n\n<span class=\"hljs-comment\">\/\/ other imports<\/span>\n<span class=\"hljs-keyword\">import<\/span> Home <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/pages\/Home'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-built_in\">Error<\/span> <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/pages\/Error'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ other configured routes\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Home<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"*\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Error<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>A route with an asterisk path <code>*<\/code> is a no-match route. It only matches when no other routes do. In the above example, we linked it to the Error page component, which is the 404 no page found component:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { Link } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">Error<\/span> = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>404<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Page not found!<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Link<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">\"\/\"<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"btn\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Go Home\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Link<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 \u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-built_in\">Error<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"implement-nested-routes\">Implement Nested Routes<\/h2>\n\n\n\n<p>Nested routes are an aspect of React Router we need to understand; this feature enables us to handle routing with a different approach. It allows you to exchange specific view fragments based on the current <code>Route<\/code>.<\/p>\n\n\n\n<p>For example, if we have a user&#8217;s page on which we only want a particular section (outlet) to change while the other section remains fixed (shared layout), we can use nested routing.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/08\/img_630e4bb35c8bb.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Imagine there are four routes to an app: Profile, Posts, Friends and settings. You can have an &#8220;outlet&#8221; to display the individual page contents depending on the URL while having a shared &#8220;layout&#8221; component to display contents like an app&#8217;s navigation sidebar.<\/p>\n\n\n\n<p>This is what the routes configuration will look like in our <code>App.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ App.js<\/span>\n\n<span class=\"hljs-comment\">\/\/ Other imports<\/span>\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ Other configured routes\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/user\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">DashboardLayout<\/span> \/&gt;<\/span>} &gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">index<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Profile<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/posts\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Posts<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/friends\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Friends<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/settings\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Settings<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Route<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Let&#8217;s now explain how it works. By using a nested <code>Route<\/code>, we will have a layout that would serve as a structure for how our page will look like. This layout will hold all static data and will create a space where we want the children&#8217;s routes (nested routes) to appear using the <code>Outlet<\/code> component:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { Outlet } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> DashboardLayout = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"sidebar\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\/* Side bar Links *\/}\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"main-section\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"title\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\/* Dashboard Title *\/}\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Outlet<\/span> \/&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 \u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> DashboardLayout;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Having passed the <code>Outlet<\/code> component, any nested component of this layout route will be displayed in the outlet section.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to Create an Index Route<\/h3>\n\n\n\n<p>Now you may begin to ask yourself what will show by default. For example, when we navigate to <code>user\/posts<\/code>, the posts component will show within the outlet portion of our layout. When we navigate to <code>user\/friends<\/code>, the friends component will show in the outlet of our layout. But what will appear in the outlet when we navigate to the <code>\/user<\/code> path? This is where the <code>index<\/code> route is applicable.<\/p>\n\n\n\n<p>The index route is used in nested routing. Any component with the index route will appear in the outlet section of our layout. This route is identified with the <code>index<\/code> props, which receives no value:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">&lt;Route path=<span class=\"hljs-string\">\"\/user\"<\/span> element={&lt;DashboardLayout \/&gt;} &gt;\n\u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">index<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Profile<\/span> \/&gt;<\/span>} \/&gt;<\/span>\n&lt;<span class=\"hljs-regexp\">\/Route&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"configure-parameter-enhanced-route\">Configure Parameter-Enhanced Route<\/h2>\n\n\n\n<p>There are two approaches to router pathing: standard routes and parameter-enhanced routes. So far, we have considered various ways to implement standard routing, but now, let&#8217;s understand how to add parameters to our routing.&nbsp;<\/p>\n\n\n\n<p>Using parameter routes allows us to render content on our UI conditionally. We use data passed via our routes as conditions to decide which data shows up on our UI, without changing layouts or pages completely.<\/p>\n\n\n\n<p>For example, if we have a list of blog posts we want to display each post&#8217;s full content on a specific page. Using the non-parmeter routing method, we would have to create individual <code>Route<\/code>s and identical components for each post, which can become challenging, or even impossible, to maintain.<\/p>\n\n\n\n<p>Parameter-based routing allows us to pass parameters through the path, as the name implies. We can use that to query which content appears on our page. Let&#8217;s now see how to configure a parameter route in our <code>App.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { Routes, Route } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> Blog <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/pages\/Blog'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> SinglePost <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/pages\/SinglePost'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/blog\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Blog<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/blog\/:id\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">SinglePost<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the above, we created a route with a parameter value of <code>id<\/code>. This value can be any string. For us to access this page and load up this page on our UI, the user will need to navigate to a URL like <code>\/blog\/1<\/code>. We can replace <code>1<\/code> with any string, and the page will load up.<\/p>\n\n\n\n<p>Our path can be anything based on how we want it or the parameter we want to pass to the <code>SinglePost<\/code> component. We can have as many parameters as <code>\/blog\/:category\/:id<\/code>.<\/p>\n\n\n\n<p><strong>Note:<\/strong><em> Adding a colon before the path name shows that the value is a parameter.<\/em><\/p>\n\n\n\n<p>We fetched an array of <code>blogposts<\/code> on our blog page from a local data file. And then added a link that passes in the ID to the path dynamically:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { Link } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> posts <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/data'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> Blog = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>Blog Page<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"posts\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {posts.map((post) =&gt; (\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"post\"<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{post.id}<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span>{post.title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>{post.body}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Link<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">{<\/span>`\/<span class=\"hljs-attr\">blog<\/span>\/${<span class=\"hljs-attr\">post.id<\/span>}`} <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"btn\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Read More\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Link<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ))}\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 \u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Blog;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Let&#8217;s now see how we can fetch this URL parameter and use it to query for data within our component.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Get URL Parameters With useParams Hook<\/h3>\n\n\n\n<p>At this point, when a user navigates a route with any <code>ID<\/code>, the page shows up, but we want to get this parameter (ID) and use it to fetch the particular blog post the user wants to see. We do this with the <a href=\"https:\/\/reactrouter.com\/docs\/en\/v6\/hooks\/use-params\" target=\"_blank\" rel=\"noopener\"><code>useParams<\/code><\/a> hook.<\/p>\n\n\n\n<p>The <code>useParams<\/code> hook gives us access to an object containing all the parameters we have passed using the path name as the object key. For example, if our path is <code>user\/:id<\/code>, our object will be <code>{id: 4}<\/code>.<\/p>\n\n\n\n<p>To use the <code>useParams()<\/code> hook, we first import it from <code>react-router-dom<\/code> and then get our data. In our case, we will destructure to get the <code>id<\/code> right away:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { useParams } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> posts <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/data'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> SinglePost = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> { id } = useParams();\n\u00a0 \u00a0\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ ...<\/span>\n\u00a0 \u00a0 );\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> SinglePost;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We can now query for the specific post we want to showcase with the <code>id<\/code> param. Depending on how we are fetching our data, we might have to perform an HTTP request if it&#8217;s an API, but since we are using a local data file, we just need to find which posts <code>id<\/code> will match the <code>id<\/code> parameter:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { useParams } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> posts <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/data'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> SinglePost = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> { id } = useParams();\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> post = posts.find(<span class=\"hljs-function\">(<span class=\"hljs-params\">post<\/span>) =&gt;<\/span> post.id == id);\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> { title, body } = post;\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>{title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>{body}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 \u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> SinglePost;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"implement-programmatic-navigation\">Implement Programmatic Navigation<\/h2>\n\n\n\n<p>Programmatic navigation can be seen as the process of navigating or redirecting a user based on specific actions. For example, if a user clicks a button, signs in or signs out, or submits a form.<\/p>\n\n\n\n<p>In React Router, this done with the <a href=\"https:\/\/reactrouter.com\/docs\/en\/v6\/hooks\/use-navigate\" target=\"_blank\" rel=\"noopener\"><code>useNavigate()<\/code><\/a> hook.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Implement Programmatic Navigation With <code>useNavigate<\/code> Hook<\/h3>\n\n\n\n<p>The <code>useNavigate()<\/code> hook allows us to perform all forms of programmatic routing, such as navigation redirects and lots more.<\/p>\n\n\n\n<p>To use this hook, we would first import it from <code>react-router-dom<\/code> and then initialize the <code>navigate<\/code> method, so we can use it on any button or perform all forms of programmatic navigation.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { useNavigate } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> navigate = useNavigate();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Let&#8217;s start by seeing how to navigate backward when a button is clicked:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> navigate(-1)}&gt;Back<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We can also access a route programmatically:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { useNavigate } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> Blog = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> navigate = useNavigate();\n\n\u00a0 \u00a0 <span class=\"hljs-keyword\">const<\/span> naviagteHome = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 \u00a0 \u00a0 navigate(<span class=\"hljs-string\">'\/'<\/span>);\n\u00a0 \u00a0 };\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Blog page<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\/*\u00a0 *\/}\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{naviagteHome}<\/span>&gt;<\/span>Go Back Home<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 \u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Blog;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The navigate hook also makes it possible to pass state values via these routes, which can be retrieved with the <code>useLocation()<\/code> hook.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">navigate(<span class=\"hljs-string\">\"\/blog\"<\/span>, {<span class=\"hljs-attr\">state<\/span>: {authorDetails}});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>And just like we did earlier, we can access these state data via the <code>useLocation()<\/code> hook:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { useLocation } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-router-dom\"<\/span>;\n\n<span class=\"hljs-comment\">\/*...*\/<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> location = useLocation();\n<span class=\"hljs-keyword\">const<\/span> authorData = location.state;\n<span class=\"hljs-built_in\">console<\/span>.log(authorData);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"code-splitting-with-react-router\">Code Splitting With React Router<\/h2>\n\n\n\n<p>When React applications and other SPAs load the initial landing page for a user&#8217;s request it simultaneously loads the code for every other page as well, leading to a massive bundle size and a poor user experience. Code splitting allows us to break down our application so that only needed components are loaded.<\/p>\n\n\n\n<p>When we implement code splitting with React Router, our application will only load the components we have routed. We can do this with <a href=\"https:\/\/reactjs.org\/docs\/code-splitting.html#reactlazy\" target=\"_blank\" rel=\"noopener\">React.lazy()<\/a> and <a href=\"https:\/\/reactjs.org\/docs\/react-api.html#reactsuspense\" target=\"_blank\" rel=\"noopener\">React.Suspense<\/a>.<\/p>\n\n\n\n<p>The function <code>React.lazy()<\/code> enables us to render dynamic imports similarly to normal components. In contrast, <code>React.Suspense<\/code> enables us to specify the fallback prop, which takes placeholder content that would be used as a loading indicator.<\/p>\n\n\n\n<p>For example, let\u2019s implement lazy loading in our Routes configuration by using just a few routes in the <code>App.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { lazy, Suspense } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { Routes, Route } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-router-dom'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> Home = lazy(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> <span class=\"hljs-keyword\">import<\/span>(<span class=\"hljs-string\">'.\/pages\/Home'<\/span>));\n<span class=\"hljs-keyword\">const<\/span> About = lazy(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> <span class=\"hljs-keyword\">import<\/span>(<span class=\"hljs-string\">'.\/pages\/About'<\/span>));\n<span class=\"hljs-keyword\">const<\/span> Blog = lazy(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> <span class=\"hljs-keyword\">import<\/span>(<span class=\"hljs-string\">'.\/pages\/Blog'<\/span>));\n\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Suspense<\/span> <span class=\"hljs-attr\">fallback<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">div<\/span>&gt;<\/span>Loading...<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>}&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Home<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/about\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">About<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"\/blog\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Blog<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Routes<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Suspense<\/span>&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n};\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"the-future-of-react-router\">Remix: The Future of React Router<\/h2>\n\n\n\n<p>On March 23rd 2022, <a href=\"https:\/\/twitter.com\/ryanflorence\" target=\"_blank\" rel=\"noopener\">Ryan Florence<\/a> published an article on the Remix blog, \u201c<a href=\"https:\/\/remix.run\/blog\/remixing-react-router\" target=\"_blank\" rel=\"noopener\">Remixing React Router<\/a>\u201d. This post contained a lot of downsides the current React Router has and how they have started <a href=\"https:\/\/beta.reactrouter.com\/en\/dev\" target=\"_blank\" rel=\"noopener\">upgrading the current package to include some remix actions<\/a> to solve these problems.<\/p>\n\n\n\n<p>Currently, we fetch data within our components, but most of the time, we want the data to load up immediately after our application renders. This means that we perform a <em>render+fetch<\/em> request. This definitely will slow down our page load time and affects user experience (UX). When performing these render+fetch requests in nested components, your app is likely to become slow.<\/p>\n\n\n\n<p>Here is an example from the <a href=\"https:\/\/remix.run\/blog\/remixing-react-router\" target=\"_blank\" rel=\"noopener\">blog post<\/a>, if we have nested routes in which each component fetches data from a server:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">&lt;Routes&gt;\n\u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">Root<\/span> \/&gt;<\/span>}&gt;\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\"projects\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">ProjectsList<\/span> \/&gt;<\/span>}&gt;\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Route<\/span> <span class=\"hljs-attr\">path<\/span>=<span class=\"hljs-string\">\":projectId\"<\/span> <span class=\"hljs-attr\">element<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">ProjectPage<\/span> \/&gt;<\/span>} \/&gt;\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Route<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Route<\/span>&gt;<\/span><\/span>\n&lt;<span class=\"hljs-regexp\">\/Routes&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In a situation whereby the <code>Root<\/code> component requests to get the user details, the <code>ProjectList<\/code> component requests to get the project lists of the user, and then the <code>ProjectPage<\/code> component requests to get a single project with its details based on the passed <code>Id<\/code>. Performing all these requests one-by-one would take longer than having to perform all these requests at once.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/08\/img_630e4bb44b28e.png\" alt=\"\"\/><figcaption><em>Instead of 3 assets loading one-by-one, 1 second at a time, within 3 seconds, they can all load simultanously in 1 second. Image by Ryan Florence<\/em><\/figcaption><\/figure>\n\n\n\n<p>In the future version of React Router, which is currently being <a href=\"https:\/\/beta.reactrouter.com\/en\/dev\" target=\"_blank\" rel=\"noopener\">released in development mode<\/a>, many changes and improvements are coming, all intending to improve user experience. When it comes to data fetching, data will be fetched when declaring routes and passed into the components to consume immediately using the <code>useLoaderData()<\/code> hook.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">&lt;Route\n\u00a0 \u00a0 path=<span class=\"hljs-string\">\":projectId\"<\/span>\n\u00a0 \u00a0 element={&lt;Projects \/&gt;}\n\u00a0 \u00a0 loader={<span class=\"hljs-keyword\">async<\/span> ({ signal, params }) =&gt;\n\u00a0 \u00a0 \u00a0 fetch(<span class=\"hljs-string\">`\/api\/projects\/<span class=\"hljs-subst\">${params.projectId}<\/span>`<\/span>, { signal })\n\u00a0 \u00a0 }\n\u00a0 \/&gt;\n&lt;<span class=\"hljs-regexp\">\/Route&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We will consume the data in our application this way:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">let<\/span> data = useLoaderData();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You can <a href=\"https:\/\/remix.run\/blog\/remixing-react-router\" target=\"_blank\" rel=\"noopener\">read more here<\/a> and watch the <a href=\"https:\/\/www.youtube.com\/watch?v=95B8mnhzoCM\" target=\"_blank\" rel=\"noopener\">recent talk by Ryan Florence<\/a> at the <a href=\"https:\/\/www.youtube.com\/c\/RealWorldReact\" target=\"_blank\" rel=\"noopener\">Real World React<\/a> conference.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this guide, we have learned much about React Router Version Six and how it works to help us implement single-page routing in our React applications. We also learned how the next version of React Router would help make the user experience better and faster.<\/p>\n\n\n\n<p>Thanks for reading, and have fun coding!<\/p>\n\n\n\n<p><em>I&#8217;m Joel Olawanle, a frontend developer and technical writer interested in making the web accessible to everyone by always looking for ways to give back to the tech community. Follow me on<a href=\"https:\/\/twitter.com\/olawanle_joel\" target=\"_blank\" rel=\"noopener\"> Twitter<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In other JavaScript frameworks like Vue, the routing logic is built by the same team that works on the core framework, meaning that we don&#8217;t need an externally written package or dependency. In React, there is no official package to handle routing; instead, we depend on the most popular and standard library, React Router. This article provides a comprehensive guide to React Router.<\/p>\n","protected":false},"author":1,"featured_media":16251,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[],"persona":[29],"blog-programming-language":[61],"keyword-cluster":[],"class_list":["post-16159","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/16159","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/comments?post=16159"}],"version-history":[{"count":16,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/16159\/revisions"}],"predecessor-version":[{"id":21539,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/16159\/revisions\/21539"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media\/16251"}],"wp:attachment":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media?parent=16159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/categories?post=16159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/tags?post=16159"},{"taxonomy":"persona","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/persona?post=16159"},{"taxonomy":"blog-programming-language","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/blog-programming-language?post=16159"},{"taxonomy":"keyword-cluster","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/keyword-cluster?post=16159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}