does anyone have experience with React routers?Is there a way to create a list of routes and hold it in a usestate? When i try to do the [... prevCountryRoutes]
i get the error that prevCountryRoutes is not iterable
const [countriesWithRouteList,setCountriesWithRouteList]=React.useState(JSON.parse(localStorage.getItem("countriesWithRouteList")) || [])
const [countryRoutes,setCountryRoutes]=React.useState()
function addCountryRoute(co){
if(countriesWithRouteList.filter(el => el == co) == null){
console.log('already route exists')
}else{
console.log('country page being added')
setCountryRoutes((prevCountryRoutes)=>{
const newRoute = <Route
key={nanoid()}
path={`/countrypage/${co.replace(/ /g, ' ')}`}
element={
<CountryPage
country={co}
holidays={holidays}
handleDeleteClick={handleDeleteClick}
handleFormSubmit={handleFormSubmit}
/>
}
/>
return(
[...prevCountryRoutes, newRoute]
)
})
}
setCountriesWithRouteList(prevList => [...prevList, co])
}
CodePudding user response:
Initialize countryRoutes
with an array, so the first time can be iterable.
const [countryRoutes,setCountryRoutes] = React.useState([])
CodePudding user response:
The error you are asking about is cause by not declaring an initial countryRoutes
state that is iterable. It's undefined.
Anyway, it's a React anti-pattern to store React components and JSX in state. Just store the data and render the derived JSX from state.
I suggest the following refactor:
const [countries, setCountries] = React.useState(JSON.parse(localStorage.getItem("countries")) || []);
function addCountryRoute(co){
if (countries.some(el => el.co === co)){
console.log('already route exists')
} else {
console.log('country page being added')
setCountries((countries) => countries.concat({
id: nanoid(),
co,
}));
}
}
...
{countries.map(country => (
<Route
key={country.id}
path={`/countrypage/${co.replace(/ /g, ' ')}`}
element={
<CountryPage
country={co}
holidays={holidays}
handleDeleteClick={handleDeleteClick}
handleFormSubmit={handleFormSubmit}
/>
}
/>
))}
And instead of mapping a bunch of routes that differ only in the country path segment, render just a single route where the country code is a route path parameter and the CountryPage
component uses the useParams
hook to get the code.
Example:
<Route
path="/countrypage/:country"
element={
<CountryPage
holidays={holidays}
handleDeleteClick={handleDeleteClick}
handleFormSubmit={handleFormSubmit}
/>
}
/>
CountryPage
const { country } = useParams();