Back to Course |
React.js Client Parking App: Step-by-Step

Named routes

As you already noticed, React Router doesn't have a centralized route config, so there's nothing to name. React Router provides the correct primitives and lets the community create higher-level APIs around them if needed.

This is exactly what we are going to do in this lesson.

  1. Create a new file src/routes/index.jsx.
const routeNames = {
'home': '/',
'register': '/register',
}
 
function route(name, params = {}) {
let url = routeNames[name]
 
for (let prop in params) {
if (Object.prototype.hasOwnProperty.call(params, prop)) {
url = url.replace(`:${prop}`, params[prop])
}
}
 
return url
}
 
export { route }

The constant routeNames is going to hold our route name as the key, and route URL as the value.

Helper function route() will act in the same way as Laravel's route() function. The first argument is going to accept the route name. The second argument will accept route parameters and then return the URL.

  1. Now update the src/main.jsx file with the following content.
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import App from '@/App'
import Home from '@/views/Home'
import Register from '@/views/auth/Register'
import '@/assets/main.css'
import { route } from '@/routes'
 
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route path={ route('home') } element={<App />}>
<Route index element={<Home />} />
<Route path={ route('register') } element={<Register />} />
</Route>
</Routes>
</BrowserRouter>
</React.StrictMode>,
)

We imported our helper function route() and can use it like this.

<Route path={ route('register') } element={<Register />} />

Note that JavaScript is a case-sensitive language. Route and route have two completely different identities.

  1. We also would like to use <NavLink> in the same way. To have properties in our component first we need to install the prop-types package.
npm install prop-types --save

React.PropTypes has moved into a different package since React v15.5.

Now it is time to create a new component src/components/NamedLink.jsx to wrap that functionality inside.

import PropTypes from 'prop-types'
import { NavLink } from 'react-router-dom'
import { route } from '@/routes'
 
function NamedLink(props) {
return (
<NavLink
end
to={ route(props.name) }
className={({ isActive }) => isActive ?
'text-blue-600 underline' :
'text-blue-600'
}
>
{ props.children }
</NavLink>
)
}
 
NamedLink.propTypes = {
name: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
}
 
export default NamedLink

Our new <NamedLink> component has all the features of <NavLink> and has two properties.

name will be our route name, and children are the content inside this component which will be passed further to <NavLink>.

Now we can consume it like in the example below.

import NamedLink from '@/components/NamedLink'
<NamedLink name="register">
Register
</NamedLink>
  1. Finally update the src/App.jsx file with the following content.
import { Outlet } from 'react-router-dom'
import NamedLink from '@/components/NamedLink'
 
function App() {
return (
<div className="App">
<header className="py-6 bg-gray-100 shadow">
<div className="container md:px-2 px-4 mx-auto">
<nav className="flex gap-4 justify-between">
<div className="flex gap-4 items-center">
<h2 className="text-xl font-bold">
<div
className="inline-flex items-center justify-center bg-blue-600 w-6 h-6 text-center text-white rounded mr-1"
>
P
</div>
myParking
</h2>
<NamedLink name="home">
Home
</NamedLink>
</div>
<div className="flex gap-4 items-center">
<NamedLink name="register">
Register
</NamedLink>
</div>
</nav>
</div>
</header>
<div className="container md:px-2 px-4 pt-8 md:pt-16 mx-auto">
<Outlet />
</div>
</div>
)
}
 
export default App

Having custom components has huge benefits. Code looks cleaner, components are reusable, and reduces the number of places to update if changes are needed. For example, now you just need to update NamedLink if you want to display all links in a different color.