React使用Axios请求数据如何在页面渲染前赋值避免map报错
问题根源
你遇到的报错本质是初始状态类型不匹配导致的:
- 你给
resultData设置的初始值是{}(空对象),而map是数组原型上的方法,对象本身没有该方法 - Axios发送请求是异步行为,页面首次渲染时请求还未返回,
resultData还是初始的空对象,此时调用map方法就会抛出resultData.map is not a function的错误 - 你注释代码等页面渲染完成再取消注释能正常运行,是因为此时请求已经返回,
resultData已经被赋值为接口返回的数组,所以调用map不会报错
解决方案
1. 修改初始状态值
把resultData的初始值改为空数组,匹配后续接口返回的数组类型,首次渲染时调用map也不会报错:
// 原代码 const [resultData, setResultData] = useState({}); // 修改后 const [resultData, setResultData] = useState([]);
2. 增加类型判断(更稳妥)
如果不能完全确定接口返回的result字段一定是数组,可以在调用map前先做类型校验,避免接口返回异常时页面报错:
const listItems = Array.isArray(resultData) ? resultData.map((d) => <li key={d.value}>{d.value}</li>) : [];
3. 可选优化:增加加载状态、合并请求
你当前代码对同一个接口发起了两次重复请求,可以合并为一次请求减少网络开销,同时增加加载状态提升用户体验:
import React, { useState, useEffect } from "react"; import "./App.css"; import axios from "axios"; const Url = "someAPi"; function App() { const [baseData, setBaseData] = useState({}); const [resultData, setResultData] = useState([]); const [loading, setLoading] = useState(true); // 新增加载状态 // 合并两个请求为同一个 useEffect(() => { const fetchData = async () => { try { const response = await axios.get(Url); setBaseData(response.data); setResultData(response.data.result || []); } catch (err) { console.error('接口请求失败', err); } finally { setLoading(false); } }; fetchData(); }, []); const listItems = resultData.map((d) => <li key={d.value}>{d.value}</li>); // 加载中时展示提示,避免空白 if (loading) return <div>数据加载中...</div>; return ( <div className="App"> <header className="App-header"> <h2>generated fees</h2> </header> <div className="info-container"> <h5 className="info-item">{baseData.status}</h5> <h5 className="info-item">{baseData.message}</h5> {/* 增加数组长度判断,避免索引越界 */} <h5 className="info-item">{listItems.length >= 2 ? listItems[1] : '暂无数据'}</h5> </div> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

