React中async/await调用axios获取数据后map报错如何解决
报错原因
- 状态初始值类型不匹配:
images的初始值设为了空对象{},组件首次渲染时接口还未返回数据,此时images是对象类型,不存在map方法,直接调用就会触发报错。 - React状态更新为异步行为:调用
setImages后立刻读取images、执行images.forEach,拿到的还是更新前的旧状态(初始空对象),自然无法调用数组方法。控制台打印的接口返回值是数组,仅代表接口响应格式正确,不代表首次渲染阶段images已经被更新为数组。 - 遍历渲染逻辑存在额外问题:遍历时
key取的是整个images数组的id属性,传递给子组件的也是整个数组而非当前遍历项,即使map不报错也会出现渲染异常。
修复步骤
- 将
images的初始值从空对象改为空数组,和接口返回的类型保持一致 - 移除
setImages后立刻操作images状态的代码,需要操作接口返回数据时直接使用接口响应的结果即可,不要依赖刚触发更新的state - 修正map遍历逻辑,使用当前遍历项的唯一id作为key,给子组件传递当前遍历项而非整个数组
- 单独增加加载状态控制,避免空数组被判断为真值导致加载态失效
修复后的完整代码:
import { useState, useEffect } from "react"; import axios from "axios"; import DisplayData from "./DisplayData"; function Home() { // 初始值改为空数组,匹配接口返回的数组类型 const [images, setImages] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { const getApi = async () => { try { const tempData = await axios.get( "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=10&api_key=" ); setImages(tempData.data.photos); // 需要操作返回数组直接用接口响应结果,不要读取刚set的state tempData.data.photos.forEach(element => { console.log(element); }); } catch (err) { console.error("接口请求失败:", err); } finally { setLoading(false); } }; getApi() }, []); if (loading) { return <h1>Waiting</h1>; } return ( <div> <h1>Home</h1> {/* 修正key取值和传递的子组件参数,使用当前遍历项item */} {images.map((item) => ( <DisplayData key={item.id} images={item} /> ))} </div> ); } export default Home;
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

