React.js中如何用Map方法将全部Axios响应数据存入State
问题根因与解决方案
问题根因
你遇到的问题是React状态更新的闭包陷阱导致的:
- React状态更新是异步且批量处理的,同一渲染周期内多次调用
setState,拿到的始终是当前闭包中的旧状态值 - 你的
useEffect依赖为空数组,内部获取到的expensesData永远是初始化的空数组[],循环调用setExpensesData时每次都是基于空数组添加新元素,之前的更新都会被覆盖,最终只会保留最后一次添加的对象。
最优解决方案:一次性更新状态
不需要循环调用setState,直接把接口返回的所有数据处理成目标格式后一次性存入状态,性能最好,逻辑也最简单:
const [expensesData , setExpensesData] = useState([]) useEffect(() => { axios.get('API-address') .then(res => { // 先把所有数据处理成你需要的格式 const formattedData = res.data.map(info => ({ info })) // 一次性更新状态 setExpensesData(formattedData) }) .catch(e => console.log(e)) } , [])
次优解决方案:使用函数式状态更新
如果确实需要逐个添加元素,调用setState时传入函数获取最新的前序状态,避免闭包陷阱:
res.data.map(info => { setExpensesData(prevState => [ ...prevState, { info } ]) })
注:这种方式会触发多次状态重渲染,性能不如一次性更新,非必要不推荐使用。
内容的提问来源于stack exchange,提问作者Kasra Habibbeygi
相关产品推荐
相关产品推荐

