As React developers, we often need to work with routing to display different views based on the URL path. However, when dealing with multiple routes, it’s crucial to understand how to properly structure these routes, especially when you’re trying to render more than one component at a time. I’ll walk you through an error you might encounter with React Router, explain how to fix it, and show you how to implement additional routing functionality for a more robust application.
Code Error
How can I get both pages loaded at the same time on the server?
// App.js
import './App.scss';
import { Router , Route } from 'react-router-dom';
import Layout from './components/Layout';
import Home from './components/Home';
function App() {
return (
<Routes>
<Route path="/" element={<Layout />}/>
<Route index element={<Home/>} />
</Routes>
);
}
export default App;
// Layout.js
import Sidebar from '../Sidebar';
import { Outlet } from 'react-router-dom';
const Layout = () => {
return (
<div className="App">
<Sidebar /> {/* Code for Side bar is given below */}
<div className="page">
<span className="tags top-tags"><body></span>
<Outlet />
<span className="tags bottom-tags">
</body>
<br />
<span className="bottom-tag-html"></html></span>
</span>
</div>
</div>
)
}
export default Layout;
// Home.js
import './index.scss'
const Home =()=> {
return(
<div className="container home-page">
<h1>Hi, I am<br/></h1>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Vitae magnam nesciunt dicta eos.</p>
</div>
)
}
export default Home;
Error Explanation
If you’re working with React Router and encountering the issue where only one component renders, specifically the <Home />
component, but not the <Layout />
, it likely has to do with improper routing configuration. The error arises from using outdated react-router-dom
components that were designed for earlier versions of React Router.
Here’s the core issue:
- You’re using the
<Router>
and<Route>
components, which are part of React Router v5 and earlier. - In React Router v6 and beyond, the correct components are
<BrowserRouter as Router>
,<Routes>
, and<Route>
. Theelement
prop is used to specify the component to render.
Let’s explore how this problem manifests and how we can solve it.
What Went Wrong?
- Incorrect Routing Component: The
react-router-dom
library has evolved. In React Router v6,<Router>
and<Route>
have been replaced with<Routes>
. The newelement
prop is used to specify the component that should be rendered, whereas in earlier versions,component
was used. Here’s what’s wrong in your code:- You’re using
<Router>
and<Route>
, which belong to React Router v5. - In React Router v6, the correct components are
<BrowserRouter>
,<Routes>
, and<Route>
.
- You’re using
- Component Rendering Issue: The problem with rendering two components at the same time (i.e., both
<Layout />
and<Home />
) arises because the routes are not correctly set up. The<Outlet />
component is used in theLayout
component to render nested routes, but theHome
component is not linked properly to it.
Here’s the corrected code with proper usage of React Router v6:
Corrected Code
App.js
'./App.scss';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; // Use BrowserRouter and Routes
import Layout from './components/Layout';
import Home from './components/Home';
function App() {
return (
<Router> {/* BrowserRouter used for routing */}
<Routes> {/* Replace <Route> with <Routes> */}
<Route path="/" element={<Layout />}> {/* Layout is the parent route */}
<Route index element={<Home />} /> {/* Home is the child route rendered in Outlet */}
</Route>
</Routes>
</Router>
);
}
export default App;
Explanation of Changes:
BrowserRouter as Router
: The<Router>
component should be wrapped in<BrowserRouter>
in React Router v6 or later. This component will manage the routing for the entire app.<Routes>
Instead of<Router>
: In React Router v6, we no longer use<Route>
directly inside<Router>
. Instead, all routes should be wrapped inside a<Routes>
component.index
Route: Theindex
route renders theHome
component as the default child for theLayout
route. This helps you display both the layout and the home page in the correct order.
Layout.js
The Layout
component remains unchanged since it uses <Outlet />
to render the content of the child routes. The child route in this case will be the Home
component.
Sidebar from '../Sidebar';
import { Outlet } from 'react-router-dom';
const Layout = () => {
return (
<div className="App">
<Sidebar />
<div className="page">
<span className="tags top-tags"><body></span>
<Outlet /> {/* This will render the Home component */}
<span className="tags bottom-tags">
</body>
<br />
<span className="bottom-tag-html"></html></span>
</span>
</div>
</div>
)
}
export default Layout;
Adding More Functionality
Now that we have the core routing working, let’s expand on this by adding more routes and practicing with other features of React Router.
Add More Routes:
You can add more routes like About
, Contact
, or Profile
to practice how React Router handles multiple pages and nested routes.
// App.js
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
Nested Routes:
If you want to render additional components inside the Layout
, you can set up nested routes. For example, you could create routes for About
and Contact
inside the Layout
route.
// App.js
<Route path="/about" element={<About />} />
<Route path="contact" element={<Contact />} />
404 Not Found Route:
It’s always a good idea to have a fallback route for pages that don’t exist. You can set up a 404 route to handle non-existent URLs:
<Route path="*" element={<NotFound />} />
Redirects:
You might also want to redirect users from old pages to new ones. Use Navigate
to achieve that:
{ Navigate } from 'react-router-dom';
<Route path="/old-home" element={<Navigate to="/" replace />} />
Final Thoughts
By fixing the issue of routing with React Router v6
, you can now load both the Layout
and Home
components properly. This was achieved by correctly using the <Routes>
, <Route>
, and <BrowserRouter>
components. React Router v6 introduces some significant changes that simplify routing, and understanding how to set up nested routes and manage layouts effectively is key to building scalable applications.
I encourage you to practice by adding more routes, creating a 404 page, handling redirects, and exploring the full potential of react-router-dom
v6. With these tools, you’ll be well on your way to creating dynamic and responsive web applications.