尝试在反应中显示获取的数据时出现“TypeError:listOfTours.map 不是函数”
Posted
技术标签:
【中文标题】尝试在反应中显示获取的数据时出现“TypeError:listOfTours.map 不是函数”【英文标题】:"TypeError: listOfTours.map is not a function" while trying to display fetched data in react 【发布时间】:2022-01-09 00:22:18 【问题描述】:这两天我一直在苦苦挣扎,经过数小时的反复试验,我无法解决它。
我想要实现的是我可以显示我从后端获取的获取的数据。我在不同的网站上看到了几个例子,但我无法让它工作。
这是我的代码和我得到的错误:
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语句,但它也不起作用。
有人有什么想法吗,还是我错过了什么?
【问题讨论】:
似乎response.data
有一个名为status
的属性,这意味着它是一个对象而不是数组。当您调用setListOfTours(response.data)
时,您将尝试在该对象上调用map
,这是无法完成的。你的response
是什么样的?
如果您在.then((response) =>
中进行控制台登录,response.data 会是什么样子?
当你 console.log() 你确定response.data
是数组吗?
@AndréKrosby 回复如下:pastebin.com/sQwu3m4X
@hotcakedev response.data 看起来像:pastebin.com/Ft11q7iF
【参考方案1】:
尝试将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 正常工作。
【讨论】:
tours.response.data = pastebin.com/Ft11q7iF, tours.response = pastebin.com/sQwu3m4X,在网络选项卡中显示状态代码 200。所以日期进来了,但不知何故 .map 不会使用数据 @Broump 刚刚更新了我的答案。看来您应该设置来自tours.response
的响应数据实际上没有数据。例如setListOfTours(tours.response);
@Broump 请告诉我我的回答对你有用。
我的意思是从技术上讲它应该可以工作,但现在我又遇到了同样的错误。我还有其他方法可以达到同样的效果吗?
@Broump,可能响应数据是字符串而不是 json 对象,所以请尝试 console.log(typeof tour.response.data)。如果它是一个数组,那么我的答案应该有效,否则您需要将 response.data 转换为 json 对象,例如 JSON.parse(response.data)
【参考方案2】:
我不知道你的 response.data
是否是数组,但如果是数组,我可以写下一些解决方案,你可以尝试所有这些
检查数组是否为空
正如我在您的代码中看到的那样,您检查的是您的数组 true
或 false
,这是错误的,因为 javscript 从不读取数组内部,您可以自己尝试 [] == []
是错误的,所以每次当您获取数据,你保持你的状态为空,因为你的 if 语句总是返回 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]);
此代码会将所有对象放入您的数组中并更新状态
如果其中一些有用,请告诉我
【讨论】:
以上是关于尝试在反应中显示获取的数据时出现“TypeError:listOfTours.map 不是函数”的主要内容,如果未能解决你的问题,请参考以下文章
将 no-cors 包含在标头中以获取 react.js 中的 json 内容时出现奇怪的错误
尝试在终端中启动反应应用程序时出现意外令牌 (9:13) 错误
在 angularjs 中的 onInit() 方法中获取用户详细信息后尝试显示用户详细信息时出现错误