React fetch返回数据调用map提示不是函数该如何解决?
问题原因
- 初始状态设置错误:
useState({})的初始值是空对象,组件首次渲染时接口请求尚未完成,data.data为undefined,非数组类型调用map方法直接触发报错。 - 缺少空值校验:未判断目标字段是否为数组就直接调用数组方法,接口返回异常时也会触发同类型报错。
- useEffect依赖项缺失:原代码useEffect依赖数组为空,当路由参数
id发生变化时不会重新触发请求,会导致页面数据不更新。 - 异步逻辑误区:useEffect中
setData后直接打印data拿不到最新值,React的状态更新是异步的,当前作用域的data变量不会在setData调用后立刻变更。
修复方案
- 调整状态初始值,提前定义好字段结构,给数组字段默认设为空数组:
const [data, setData] = useState({ data: [] });
- 调用
map方法前添加可选链做非空校验,避免非数组类型调用方法:
将data.data.map修改为data?.data?.map - 补充useEffect依赖项,将路由参数
id加入依赖数组,保证id变化时重新拉取数据。 - 如需打印接口返回值,可在fetch的成功回调中直接打印接口返回的结果。
完整修正代码
export default function Trainers() { // 修正初始值结构 const [data, setData] = useState({ data: [] }); const { id } = useParams(); useEffect(() => { fetch(`http://localhost:4000/api/v1/trainers/${id}`) .then((response) => response.json()) .then((res) => { setData(res); // 在这里打印可以拿到正确的接口返回数据 console.log(res); }); // 把id加入依赖数组 }, [id]); return ( <div> <Pos> <SmallHeadline> <Cap>Trainer</Cap> </SmallHeadline> </Pos> {/* 添加可选链做安全校验 */} {data?.data?.map((course, key) => { return ( <TrainerCard key={key}> <TrainerImgCon style={{ backgroundImage: `url(${course.asset.url})` }} ></TrainerImgCon> <TrainerTxt>{course.trainerName}</TrainerTxt> </TrainerCard> ); })} </div> ); }
内容的提问来源于stack exchange,提问作者DNH
相关产品推荐
相关产品推荐

