I'm trying to display my listOfTours as individuals divs's in react, but I'm getting the following error:
TypeError: listOfTours.map is not a function
for the first 1 or 2 seconds it displays everything correctly but then the error comes up
My Array:
const [listOfTours, setListOfTours] = useState([
{
tour_date: "2020-04-24",
tour_distance: 15,
tour_duration: 60,
tour_elevation_down: 245,
tour_elevation_up: 245,
tour_name: "Fahrradtour 24.04.2020 19:07",
tour_sport: "mtb",
},
{
tour_date: "2020-04-23",
tour_distance: 34,
tour_duration: 143,
tour_elevation_down: 426,
tour_elevation_up: 426,
tour_name: "Fahrradtour 23.04.2020",
tour_sport: "mtb",
}
]);
My Code to Map over the Array:
return (
<div>
<div className="tourDisplay">
{listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
})}
</div>
</div>
);
It seems to have something todo with how i get my data to react
useEffect(() => {
axios
.get("/api/all-tours", {
headers: {
"x-access-token": localStorage.getItem("token"),
},
})
.then((response) => {
if (response.data.status === "error") {
console.log(response.data.status);
} else {
setListOfTours(response.data);
}
});
});
Since you're returning your data
that you put into the State from an asyncrhonous call, it happens that when you invoke the function, your state is empty and the map
doesn't find any data. You can solve easily this problem in different way; one of them could be use a loading state
.
const [loading, setLoading] = useState(true);
Then you can modify your useEffect
like that:
useEffect(() => {
axios
.get("/api/all-tours", {
headers: {
"x-access-token": localStorage.getItem("token"),
},
})
.then((response) => {
if (response.data.status === "error") {
console.log(response.data.status);
} else {
setListOfTours(response.data);
}
}).then(_ => {
setLoading(false);
});
});
And on the return
you should add this:
if(loading) return <p>Loading...</p>
else return (
<div>
<div className="tourDisplay">
{listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
})}
</div>
</div>
);
Eventually, you can move the loading
near the map function, so:
{loading ? <p>Loading...</p>
: (listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
}))}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.