Skip to main content

React Router

npm install react-router-dom localforage match-sorter sort-by

React Router example application

  • In the following example, we create routing for an app with three components Home, About and Contact.
  • The router is rendered in the application root in main.jsx Router example

The required components:

// Home.jsx 
export default function Home() {
return(<h1>Welcome to my app</h1>);
}

// About.jsx
export default function About() {
return(<h1>With my app you can...</h1>);
}

// Contact.jsx
export default function Contact() {
return(<h1>Email: myapp@contact.com</h1>);
}
  • App component contains the application navigation.
  • Link components let the user navigate to another page in router
  • Component Outlet renders the page navigated to within the App view
App.jsx
import { Link, Outlet } from 'react-router-dom';

function App() {
return (
<div className="App">
<nav>
<Link to={"/"}>Home</Link>
<Link to={"/about"}>About</Link>
<Link to={"/contact"}>Contact</Link>
</nav>
<Outlet />
</div>
);
}
  • First, we will create BrowserRouter in the root of the application (main.jsx) using the createBrowserRouter function. It takes an array of route objects as an argument.
main.jsx
import App from './App';
import { createBrowserRouter } from 'react-router-dom';

const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
]);

  • In the example code, we create the root route that renders our App component when user navigates to the /- endpoint.
main.jsx
const router = createBrowserRouter([
// root route
{
path: "/",
element: <App />,
},
]);
  • The path property is a path pattern. When it matches to current URL, the element will be rendered.
  • If a route path pattern ends with /* it will match any characters following the /.
  • Next, we will create rest of our routes. They are created as children of the root route.
  • One of the children is defined as the index route. It is rendered at the root path /.
main.jsx
const router = createBrowserRouter([  // Import components that are used in routes
{
path: "/",
element: <App />,
children: [ // children are nested routes with a route
{
element: <Home />,
index: true // index route does not need any path
},
{
path: "about", // path can be defined relative to the parent path
element: <About />,
},
{
path: "contact",
element: <Contact />,
},
]
}
]);
  • Finally, we will use RouterProvider component to render the router and pass our routes to this component using the router prop.
main.jsx
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
...

const router = createBrowserRouter([
{
path: "/",
element: <App />,
...

ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>,
);

Error handling

  • Navigation to a path that does not exist causes an error, and the React Router default error component is rendered.
  • We can create an own component that will be rendered when error happens.
  • The errorElement property can be used to define an element that is rendered if the throws an exception.
  • If the errorElement is defined for the root route it applies everywhere in the router
const router = createBrowserRouter([
{
path: "/",
element: <App />,
errorElement: <Error />
},
...

Error component

  • Hook useRouteError can be used in an errorElement. It returns the error that was thrown.
// Error.jsx
import { useRouteError } from "react-router-dom";

export default function Error() {
const error = useRouteError();
console.log(error); // check the console to see the full contents of the error object

return (
<div>
<h1>Page not found</h1>
<p>{error.data}</p>
</div>
);
}

Further reading