20
React-Router-dom 6! What changed?
There I was in the middle of my little project when I realized that react router had updated from v5 into v6.
I made everything right and my routes did not work. That made me so annoyed that I've returned into the old version and finished that project.
Later after that, I've started to learn about those changes and everything made sense. I could understand what was happening with my routes. Well... That inspired me to start my blog with that headline.
Yes! Now, what we have instead is this functionality called Routes and the syntax is also different.
This was usual on v5 version usage:
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import Home from 'path-to-home';
import Cart from 'path-to-cart';
<Switch>
<Route exact path="/"
<Home/>
</Route>
<Route path="/cart"
<Cart/>
</Route>
</Switch>
Noticed that rather than passing the component as a child "loose" inside a <Rote/>
, now we need a pass as a prop using this new tag called element
.
exact
doesn't necessary, and an order from routes doesn't matter anymore.
This new version is smarter.
If you have routes with descendant route, what defined in other components, use a trailing * in their path to indicate they match deeply. After doing that, then React-Router-6 will find the better option to route it. So must be easier.
Let's take a look into how we should be using from now on:
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import Home from 'path-to-home';
import Cart from 'path-to-cart';
<Routes>
<Route path="/" element={ <Home/> } />
<Route path="/cart" element={ <Cart/> } />
</Routes>
It's important to say: the use of Routes is mandatory now, so if you have one or more routes, you need to use it inside a <Routes/>
.
On top of that, if you have a nested route, you can define it on the same page!!
// app.jsx
import React from 'react';
import { Route, Routes, Navegate } from 'react-router-dom';
<Routes>
<Route path="/" element={ <Navegate _replace_ to="/welcome" /> }>
<Route path="/welcome/*" element={ <Welcome/> } >
<Route path="new-user" element={ <p>Welcome, new user!</p> } />
</Route>
<Route path="/cart" element={ <Cart/> } />
</Routes>
This replace
on <Navegate>
is optional to use, but semantic correct when used to replace pages.
If you don't use it, the react-router-6 will push the page as well. Have you noticed another change on the above code?
If you declare on the same page, you need to use <Outlet/>
to indicate the correct position on the nested page as you can see on the code below:
// Welcome.jsx
import React from 'react';
import { Link, Outlet } from 'react-router-dom';
const Welcome () => {
return (
<section>
<h1> This is you particular space</h1>
<Outlet />
<Link to="/home"> Return to Home <Link/>
</section>
);
};
Advanced changes
All <Route children>
from the v5 version changed to <Route element>
in v6. This should be as simple as moving your route element from the child position to a named element prop.
import { NavLink } from "react-router-dom";
<NavLink activeClassName= { classes.active } to='/home' >
Home
</NavLink>
We continue having a <Link/>
and <NavLink/>
nothing change with then. However, what did change was the activeClassName props, it doesn't exist
anymore.
Instead that, you need to write a most verbose code. You'll need to use an argument with a function to promote this change. And then you find an isActive property inside an object on react-router-6 and do a simple conditional ternary statement to define.
import { NavLink } from "react-router-dom";
<NavLink className= {
(thisNav) => thisNav.isActive ? class.active : ''}
to='/home'>
Home
</NavLink>
I never used { useHistory }
yet, even so, this hook is used to navigate between pages history.
Maybe is because that the name changed to { useNavigate }
, to turns the code more legible, or clean.
I've noticed, now we can use a negative number to indicate where we want to send the user. But this I'll explain in another moment.
For now, they removed this other things, temporary:
References:
github/react-router
react-router-v6
20