I'm using react-router-dom version 6.0.2 here and the "Render" props isn't working, every time I got to the url mentioned in the Path of my Route tag it keeps throwing me this error - "Matched leaf route at location "/addRecipe" does not have an element. This means it will render an with a null value by default resulting in an "empty" page.". Can someone please help me with this issue
import './App.css';
import Home from './components/Home';
import AddRecipe from './components/AddRecipe';
import items from './data';
import React, { useState } from 'react';
import {BrowserRouter as Router, Routes, Route} from 'react-router-dom';
const App = () => {
const [itemsList, setItemsList] = useState(items)
const addRecipe = (recipeToAdd) => {
setItemsList(itemsList.concat([recipeToAdd]));
}
const removeItem = (itemToRemove) => {
setItemsList(itemsList.filter(a => a!== itemToRemove))
}
return (
<Router>
<Routes>
<Route path="/addRecipe" render={ ({history}) => {
return (<AddRecipe onAddRecipe={(newRecipe) => {
addRecipe(newRecipe);
history.push('/');
} } />);
} } />
</Routes>
</Router>
);
}
export default App;
CodePudding user response:
In react-router-dom version 6, you should use element prop for this.
I suggest your read their document on upgrading from version 5 where they explain the changes.
For your problem, you should write something like this:
<Route
path="/addRecipe"
element={
<AddRecipe
onAddRecipe={(newRecipe) => {
addRecipe(newRecipe);
history.push('/');
}
/>
}
/>
CodePudding user response:
The Route
component API changed significantly from version 5 to version 6, instead of component
and render
props there is a singular element
prop that is passed a JSX literal instead of a reference to a React component (via component
) or a function (via render
).
There is also no longer route props (history
, location
, and match
) and they are accessible only via the React hooks. On top of this RRDv6 also no longer surfaces the history
object directly, instead abstracting it behind a navigate
function, accessible via the useNavigate
hook. If the AddRecipe
component is a function component it should just access navigate
directly from the hook. If it unable to do so then the solution is to create a wrapper component that can, and then render the AddRecipe
component with the corrected onAddRecipe
callback.
Example:
const AddRecipeWrapper = ({ addRecipe }) => {
const navigate = useNavigate();
return (
<AddRecipe
onAddRecipe={(newRecipe) => {
addRecipe(newRecipe);
navigate('/');
}}
/>
);
};
...
const App = () => {
const [itemsList, setItemsList] = useState(items);
const addRecipe = (recipeToAdd) => {
setItemsList(itemsList.concat([recipeToAdd]));
};
const removeItem = (itemToRemove) => {
setItemsList(itemsList.filter(a => a !== itemToRemove))
};
return (
<Router>
<Routes>
<Route
path="/addRecipe"
element={<AddRecipeWrapper addRecipe={addRecipe} />}
/>
</Routes>
</Router>
);
};