Reputation: 109
In the old version 5 of react router dom, I used 'Redirect' to do the route redirection, and the code of my application was this:
import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom';
import Navbar from './core/components/Navbar';
import Admin from './pages/Admin';
import Catalog from './pages/Catalog';
import ProductDetails from './pages/Catalog/components/ProductDetails';
import Home from './pages/Home';
// BrowserRouter vai encapsular toda a aplicação, ou seja, ele vai gerenciar todas as rotas disponíveis.
// O Switch vai decidir qual rota ele tem que renderizar.
// Através do componente Route é que vamos, de fato, definir a URL de cada rota na aplicação.
const Routes = () => (
<BrowserRouter>
<Navbar />
<Switch>
<Route path="/" exact>
<Home />
</Route>
<Route path="/products" exact>
<Catalog />
</Route>
<Route path="/products/:productId">
<ProductDetails />
</Route>
<Redirect from="/admin" to="/admin/products" exact />
<Route path="/admin">
<Admin />
</Route>
</Switch>
</BrowserRouter>
);
export default Routes;
The line <Redirect from="/admin" to="/admin/products" exact />
is so that, when I arrive at the /admin page, I will be taken to the page /admin/products automatically.
After updating react router dom to version 6, I made the project changes and now the code looks like this:
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import Navbar from './core/components/Navbar';
import Admin from './pages/Admin';
import Catalog from './pages/Catalog';
import ProductDetails from './pages/Catalog/components/ProductDetails';
import Home from './pages/Home';
const RoutesPages = () => (
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/products" element={<Catalog />} />
<Route path="/products/:productId" element={<ProductDetails />} />
<Route path="/admin" element={<Navigate to="/admin/products" replace={true} />} />
<Route path="/admin" element={<Admin />} />
</Routes>
</BrowserRouter>
);
export default RoutesPages;
Since 'exact' is no longer used in version 6, I'm having the problem of not displaying anything else on the '/admin/products' page, all elements disappeared (no links, navbar, and so on) because the 'exact' had the function of guaranteeing me to be on the '/admin' page, until redirecting me to /admin/products.
How do I resolve this?
............................
up:
I'm including two codes that will help you understand how the route is being rendered for the "/admin/products" path:
import { Route, Routes, } from "react-router-dom";
import Navbar from "./components/Navbar";
import Products from "./components/Products";
import './styles.scss';
const Admin = () => (
<div className="admin-container">
<Navbar />
<div className="admin-content">
<Routes>
<Route path="/admin/products" element={<Products />} />
<Route path="/admin/categories" element={<h1>Categories</h1>} />
<Route path="/admin/users" element={<h1>Users</h1>} />
</Routes>
</div>
</div>
);
export default Admin;
import { Route, Routes } from 'react-router-dom';
import Form from './Form';
import List from './List';
const Products = () => {
return (
<div>
<Routes>
<Route path="/admin/products" element={<List />} />
<Route path="/admin/products/create" element={<Form />} />
<Route path="/admin/products/:productId" element={<h1>Editar produto</h1>} />
</Routes>
</div>
);
}
export default Products;
I've now added /* after /admin on script Routes.tsx:
const RoutesPages = () => (
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/products" element={<Catalog />} />
<Route path="/products/:productId" element={<ProductDetails />} />
<Route path="/admin" element={<Navigate to="/admin/products" replace={true} />} />
<Route path="/admin/*" element={<Admin />} />
</Routes>
</BrowserRouter>
);
export default RoutesPages;
Upvotes: 2
Views: 2334
Reputation: 203051
So it seems it is the route rendering the List
component you want rendered when the user navigates to "/admin"
, i.e. the route rendering on path "/admin/products"
.
The root admin route is correctly rendering a "*"
wildcard suffix to allow matching additional sub-routes. The Admin
component rendering the "/products"
sub-route also needs to render a "*"
wildcard suffix to match further nested sub-routes.
The RoutesPages
component should render the root routes with trailing "*"
character to allow matching sub-routes.
const RoutesPages = () => (
<>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/products/*" element={<Catalog />} />
<Route path="/admin/*" element={<Admin />} /> // match sub-routes
</Routes>
</>
);
Then the Admin
component can render an index route to redirect to the "/products"
sub-route and append a trailing "*"
character to the "/products/*"
path to allow additional sub-route matching.
const Admin = () => (
<div className="admin-container">
<Navbar />
<div className="admin-content">
<Routes>
<Route index element={<Navigate to="products" replace />} /> // redirect to desired path
<Route path="/products/*" element={<Products />} /> // match sub-routes
<Route path="/categories" element={<h1>Categories</h1>} />
<Route path="/users" element={<h1>Users</h1>} />
</Routes>
</div>
</div>
);
...
const Products = () => {
return (
<div>
<Routes>
<Route index element={<List />} /> // desired path/component
<Route path="/create" element={<Form />} />
<Route path="/:productId" element={<h1>Editar produto</h1>} />
</Routes>
</div>
);
};
Upvotes: 1