"TypeError: listOfTours.map is not a function" while trying to display fetched data in react
"TypeError: listOfTours.map is not a function" while trying to display fetched data in react
两天以来我一直在苦苦挣扎,经过数小时的反复试验我无法解决它。
我想要实现的是我可以显示从后端获取的数据。我在不同的网站上看到了几个例子,但我无法让它工作。
这是我的代码和我得到的错误:
function Tours({ isAuth: isAuth, component: Component, ...rest }) {
const [listOfTours, setListOfTours] = useState([]);
console.log(listOfTours);
const getAllTours = () =>
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);
}
});
useEffect(() => {
getAllTours();
}, []);
if (listOfTours.length > 0) {
return (
<div>
<div className="tourDisplay">
{listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
})}
</div>
</div>
);
} else {
return (
<div>
<p>Loading...</p>
</div>
);
}
}
export default withRouter(Tours);
TypeError: listOfTours.map is not a function
Tours
src/components/tours.js:32
29 | if (listOfTours.length > 0) {
30 | return (
31 | <div>
> 32 | <div className="tourDisplay">
| ^ 33 | {listOfTours.map((tour) => {
34 | return (
35 | <div>
我认为这与异步调用有关,并且 .map 无法处理空数组。因此,我在return前面使用了if语句,但也不行。
有人知道吗,还是我遗漏了什么?
尝试使 getAllTours
函数成为 Promise。
...
const [listOfTours, setListOfTours] = useState(null);
const getAllTours = async () => {
try {
// not sure if /api/all-tours is the proper API source
const tours = await axios.get("/api/all-tours", {
headers: {
"x-access-token": localStorage.getItem("token"),
},
});
// try to console.log here to make sure if the tours has responded successfully and what type of the tours.response.data has either object or array
console.log(tours.response);
console.log(typeof tours.response.data);
// this seems to be tours.response without data
if (tours.response.data) { // if (tours.response) {
// if tours.response.data is a type string, then convert it to json object
// setListOfTours(JSON.parse(tours.response.data));
setListOfTours(tours.response.data);
// setListOfTours(tours.response);
}
} catch (err) {
console.error(err);
}
}
useEffect(() => {
getAllTours();
}, [getAllTours]);
return (
<div>
{
!listOfTours
? // loading div
: <div className="tourDisplay">
{listOfTours.length > 0 && listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
})}
</div>
}
</div>
);
如果这不起作用,请检查浏览器并转到网络选项卡,然后确保 API 正常工作。
我不知道你的 response.data
数组是不是,但如果它是数组,我可以写下一些解决方案,你可以尝试所有这些
检查数组是否为空
正如我在你的代码中看到的那样,你检查的是你的数组 true
或 false
,这是错误的,因为 javscript 从不读取内部数组,你可以自己尝试 [] == []
是 false 所以每次当你获取数据时你保持你的状态为空因为你的 if 语句总是 returns false 最好的检查方法是数组是否为空你可以检查它的长度
错误
if (tours.response.data) { //it always returns false
setListOfTours(tours.response.data);
}
如果你检查你的响应数据是否undefined
也会更好
更好
if (tours.response.data.length > 0 || !tours.response.data === undefined) {
setListOfTours(tours.response.data);
}
获取前设置默认值
当您获取数据时,您的状态始终是 []
空数组,如果您尝试在控制台中打印,它永远无法读取内部值 listOfTours.tour_date
您将得到 无法读取null 的属性(读取 'tour_date') 所以在获取数据之前创建带有字符串的空对象
const defaultState = {
"tour_date": "",
"tour_distance": 0,
"tour_duration": 0,
"tour_elevation_down": 0,
"tour_elevation_up": 0,
"tour_name": "",
"tour_sport": ""
}
const [listOfTours, setListOfTours] = useState([defaultState]);
并且该代码将放松您的反应并且不会弹出错误,我在 null 开头提到的内容 属性
如果你声明有默认值
,你可以使简单的三元运算符不包含.map()
元素
!listOfTours[0].tour_date === "" ?
listOfTours.map(each => {
return <div>...</div>
}) : null
传播运算符
解决该问题的最后一种方法我认为它不会奏效,但我也会包括那个方法,如果您的响应确实是数组并且反应无法识别它,您可以传播运算符
if (tours.response.data.length > 0 || !tours.response.data === undefined) {
setListOfTours([...tours.response.data]);
}
此代码会将所有对象放入您的数组中并更新状态
如果其中一些可行,请告诉我
两天以来我一直在苦苦挣扎,经过数小时的反复试验我无法解决它。
我想要实现的是我可以显示从后端获取的数据。我在不同的网站上看到了几个例子,但我无法让它工作。
这是我的代码和我得到的错误:
function Tours({ isAuth: isAuth, component: Component, ...rest }) {
const [listOfTours, setListOfTours] = useState([]);
console.log(listOfTours);
const getAllTours = () =>
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);
}
});
useEffect(() => {
getAllTours();
}, []);
if (listOfTours.length > 0) {
return (
<div>
<div className="tourDisplay">
{listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
})}
</div>
</div>
);
} else {
return (
<div>
<p>Loading...</p>
</div>
);
}
}
export default withRouter(Tours);
TypeError: listOfTours.map is not a function
Tours
src/components/tours.js:32
29 | if (listOfTours.length > 0) {
30 | return (
31 | <div>
> 32 | <div className="tourDisplay">
| ^ 33 | {listOfTours.map((tour) => {
34 | return (
35 | <div>
我认为这与异步调用有关,并且 .map 无法处理空数组。因此,我在return前面使用了if语句,但也不行。
有人知道吗,还是我遗漏了什么?
尝试使 getAllTours
函数成为 Promise。
...
const [listOfTours, setListOfTours] = useState(null);
const getAllTours = async () => {
try {
// not sure if /api/all-tours is the proper API source
const tours = await axios.get("/api/all-tours", {
headers: {
"x-access-token": localStorage.getItem("token"),
},
});
// try to console.log here to make sure if the tours has responded successfully and what type of the tours.response.data has either object or array
console.log(tours.response);
console.log(typeof tours.response.data);
// this seems to be tours.response without data
if (tours.response.data) { // if (tours.response) {
// if tours.response.data is a type string, then convert it to json object
// setListOfTours(JSON.parse(tours.response.data));
setListOfTours(tours.response.data);
// setListOfTours(tours.response);
}
} catch (err) {
console.error(err);
}
}
useEffect(() => {
getAllTours();
}, [getAllTours]);
return (
<div>
{
!listOfTours
? // loading div
: <div className="tourDisplay">
{listOfTours.length > 0 && listOfTours.map((tour) => {
return (
<div>
<div>Tourname: {tour.tour_name}</div>
<div>...other values</div>
</div>
);
})}
</div>
}
</div>
);
如果这不起作用,请检查浏览器并转到网络选项卡,然后确保 API 正常工作。
我不知道你的 response.data
数组是不是,但如果它是数组,我可以写下一些解决方案,你可以尝试所有这些
检查数组是否为空
正如我在你的代码中看到的那样,你检查的是你的数组 true
或 false
,这是错误的,因为 javscript 从不读取内部数组,你可以自己尝试 [] == []
是 false 所以每次当你获取数据时你保持你的状态为空因为你的 if 语句总是 returns false 最好的检查方法是数组是否为空你可以检查它的长度
错误
if (tours.response.data) { //it always returns false
setListOfTours(tours.response.data);
}
如果你检查你的响应数据是否undefined
也会更好
更好
if (tours.response.data.length > 0 || !tours.response.data === undefined) {
setListOfTours(tours.response.data);
}
获取前设置默认值
当您获取数据时,您的状态始终是 []
空数组,如果您尝试在控制台中打印,它永远无法读取内部值 listOfTours.tour_date
您将得到 无法读取null 的属性(读取 'tour_date') 所以在获取数据之前创建带有字符串的空对象
const defaultState = {
"tour_date": "",
"tour_distance": 0,
"tour_duration": 0,
"tour_elevation_down": 0,
"tour_elevation_up": 0,
"tour_name": "",
"tour_sport": ""
}
const [listOfTours, setListOfTours] = useState([defaultState]);
并且该代码将放松您的反应并且不会弹出错误,我在 null 开头提到的内容 属性
如果你声明有默认值
,你可以使简单的三元运算符不包含.map()
元素
!listOfTours[0].tour_date === "" ?
listOfTours.map(each => {
return <div>...</div>
}) : null
传播运算符
解决该问题的最后一种方法我认为它不会奏效,但我也会包括那个方法,如果您的响应确实是数组并且反应无法识别它,您可以传播运算符
if (tours.response.data.length > 0 || !tours.response.data === undefined) {
setListOfTours([...tours.response.data]);
}
此代码会将所有对象放入您的数组中并更新状态
如果其中一些可行,请告诉我