Before upgrading to v6 I had this part of code, which worked as it should:
//before
return (
<BrowserRouter>
<Route render={(props) => (
<div className={`layout ${themeReducer.mode}`}>
<Sidebar {...props}/>
<div className="layout__content">
<TopNav/>
<div className="layout__content-main">
<Switch>
<Route path='/' exact component={Dashboard} />
<Route path='/activity' component={Activity} />
</Switch>
</div>
</div>
</div>
)}/>
</BrowserRouter>
)
After upgrading I only changed Switch
to Routes
and component
to element
and expected it to work, but it didn't.
Error: A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.
Tried many things, but nothing helped. How can I make it work the way it worked before the upgrading?
//after
return (
<BrowserRouter>
<Route render={(props) => (
<div className={`layout ${themeReducer.mode}`}>
<Sidebar {...props}/>
<div className="layout__content">
<TopNav/>
<div className="layout__content-main">
<Routes>
<Route path='/' element={<Dashboard/>} />
<Route path='/activity' element={<Activity/>} />
</Routes>
</div>
</div>
</div>
)}/>
</BrowserRouter>
)
CodePudding user response:
Actually, the Route
rendered by BrowserRouter
needs to be wrapped in a Routes
component and also render JSX on the element
prop or wrap a child React component.
It appears to be a layout component so abstract it out into its own component that renders an Outlet
for the nested Route
components. If Sidebar
isn't a function component to use the React hooks then use the hooks in the layout component and pass them as props to Sidebar
as before. Note that if Sidebar
previously used the history
object that it was replaced by a navigate
function in RRDv6.
import { Outlet, useLocation, useMatch, useNavigate } from 'react-router-dom';
const Layout = () => {
const navigate = useNavigate();
const location = useLocation();
const match = useMatch();
// ... etc....
return (
<div className={`layout ${themeReducer.mode}`}>
<Sidebar
location={location}
match={match}
navigate={navigate}
...... etc....
/>
<div className="layout__content">
<TopNav/>
<div className="layout__content-main">
<Outlet /> // <-- nested routes render here
</div>
</div>
</div>
);
};
...
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />} >
<Route index element={<Dashboard />} />
<Route path="/activity" element={<Activity />} />
</Route>
</Routes>
</BrowserRouter>
)