React中遍历数组异步调用API时如何正确执行setState?
问题修复方案
核心问题说明
- 遍历过程中直接调用
setStocks(单个股票数据)会直接覆盖整个stocks数组,而非追加新数据 async函数在map中执行时会生成Promise数组,零散更新状态容易出现时序问题,导致状态不符合预期- 补充:遍历的参数名和外层
favoritesstate重名,属于不规范写法,建议修改避免潜在作用域问题
推荐修复代码(批量更新,减少重渲染)
批量等待所有请求完成后一次性更新状态,性能更优,避免多次渲染:
// 组件挂载时调用请求函数 useEffect(() => { tableFetch(); }, []); const [favorites, setFavorites] = useState(["aapl", "arlv"]); const [stocks, setStocks] = useState([]); // 拉取所有股票数据并存入state const tableFetch = async () => { // 生成所有请求的Promise数组 const requestPromises = favorites.map(async (symbol) => { const response = await fetch( `https://cloud.iexapis.com/stable/stock/${symbol}/quote?token=${token}` ); return await response.json(); }); // 等待所有请求返回 const allStockData = await Promise.all(requestPromises); // 一次性更新状态 setStocks(allStockData); }
可选修复方案(逐个加载,请求到一个就显示一个)
如果需要实现边加载边渲染的效果,可以使用状态更新的函数式写法,保证每次更新都基于上一次的最新状态:
const tableFetch = () => { favorites.map( async (symbol) => { const response = await fetch( `https://cloud.iexapis.com/stable/stock/${symbol}/quote?token=${token}` ); const stockData = await response.json(); // 函数式更新,基于历史state追加新数据,不会覆盖 setStocks(prev => [...prev, stockData]); }); }
内容的提问来源于stack exchange,提问作者Binne
相关产品推荐
相关产品推荐

