React开发中为何fetch获取的数据集在Promise链、for循环内访问stationId返回undefined
问题根源定位
- Promise链传参断裂:第一个
.then处理接口响应的块内没有显式返回解析后的JSON数据,仅执行了setData(json)和console.log(data)操作。JS Promise链规则为:上一个then没有返回值时,下一个then接收到的入参固定为undefined,这就是你在循环中访问dataset[i]["stationId"]全部返回undefined的核心原因。你之前在控制台能正常读到字段值,是因为调试时单独打印了接口返回的原始JSON,并非当前错位接收到的dataset参数。 - useState异步更新的闭包陷阱:在
setData(json)之后同步执行console.log(data),此时代码捕获的data还是组件首次渲染时的初始值(空数组),根本拿不到刚设置的新值。React的state更新为批量异步触发机制,不会在set调用后同步修改当前作用域内的变量引用。 - 循环变量作用域错误:你把循环变量
i定义在组件全局作用域,外层循环和内层循环共用同一个i做计数,内层循环每次执行都会将i赋值为dataset的最大长度,直接冲掉外层循环的计数,循环逻辑会完全走偏,达不到预期的分组效果。 - 分组数组的作用域漏洞:将
arr定义在组件函数体中,每次组件重渲染时这个变量都会被重新初始化为空数组,无法持久存储分组结果;同时原逻辑中用索引直接对比arr[i]和dataset[i]的字段,在嵌套循环的场景下完全匹配不到正确的条目,判断逻辑从根源上就是错位的。
修正后的可运行实现
const [data, setData] = useState([]); useEffect(() => { const fetchEvents = async () => { try { const response = await fetch(`http://${ip.trim()}:${port}/events/station`); const json = await response.json(); // 在拿到原始接口数据的同作用域完成分组重构,避免Promise传参错位 const groupedResult = []; for (let eventItem of json) { // 按stationId匹配对应分组项,避免索引错位问题 const existGroup = groupedResult.find(item => item.stationId === eventItem.stationId); if (!existGroup) { // 无匹配项则新建分组 groupedResult.push({ stationId: eventItem.stationId, event_type: eventItem.event_type, duration: [eventItem.duration] }); } else { // 匹配到则将当前事件的duration追加到对应分组的数组中 existGroup.duration.push(eventItem.duration); } } // 将重构后的结构存入state,供后续渲染使用 setData(groupedResult); } catch (err) { console.log(err); } }; fetchEvents(); }, []);
补充说明
- 原代码中尝试用双重嵌套for循环实现分组的写法存在大量无效判断,改用
find匹配同stationId分组项的方式,既规避了循环变量共用的问题,也不会出现索引错位导致的字段读取错误。 - 不要再在
setData之后同步读取state值,需要用到最新的分组结果时,要么在请求拿到json的同作用域直接使用,要么在组件渲染阶段读取已更新的data值即可。
内容的提问来源于stack exchange,提问作者user15607835
相关产品推荐
相关产品推荐

