You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useEffect多API调用仅首个Promise结果渲染问题

异步请求按需渲染笔记失败的解决方法

问题场景

开发笔记Web应用时,先从后端获取笔记ID列表,再通过useEffect对每个ID发起API请求,期望每个Promise resolve后立即渲染对应笔记。但实际测试中,仅首个请求的结果会被渲染,后续请求的结果虽在控制台输出但不渲染。使用Promise.all可渲染全部笔记,但需等待所有请求完成,不符合按需渲染的预期。

核心原因

问题出在state更新时的闭包捕获:在forEach循环的异步回调中,notes变量捕获的是组件初始渲染时的空数组。每个请求完成后执行setNotes([...notes, note]),都是基于这个旧的空数组添加元素,导致后续的state更新会覆盖之前的结果,最终只能看到最后一个完成的笔记(或仅首个,取决于请求完成顺序)。

解决方案

使用React的函数式state更新,给setNotes传入一个函数,该函数接收当前最新的state作为参数,返回新的state值。这样每次更新都会基于最新的state,避免闭包带来的旧值问题。

修改后的代码示例

主组件修改部分

将setNotes([...notes, note])替换为函数式更新:

.then(note =>{ 
  setNotes(prevNotes => [...prevNotes, note])
})

完整修改后的主组件useEffect片段:

useEffect(() => {
  async function fetchNotes(noteIds: NoteIds) {
    try {
      noteIds.forEach(async id => {
        return fetch("http://localhost:5086/api/notes/get/" + id)
        .then(response => response.json())
        .then(data => Note.parse(data))
        .then(note =>{ 
          setNotes(prevNotes => [...prevNotes, note])
        })
      })
    } catch (error) {
      console.error(error);
    }
  }

  if(noteIdsResponse.data) {
    fetchNotes(noteIdsResponse.data)
  }
}, [noteIdsResponse.data])

测试组件修改部分

同样将setNotes([...notes, data])替换为函数式更新:

.then(data =>{ 
  setNotes(prevNotes => [...prevNotes, data])
  console.log(data)
})

完整修改后的测试组件useEffect片段:

useEffect(() => {
  async function fetchNotes(noteIds: number[]) {
    try {
      noteIds.forEach(async id => {
        return fetch("http://localhost:5086/api/notes/get/" + id)
        .then(response => response.json())
        .then(data =>{ 
          setNotes(prevNotes => [...prevNotes, data])
          console.log(data)
        })
      })
    } catch (error) {
      console.error(error);
    }
  }

  if(!didMount.current) {
    fetchNotes(noteIds)
    didMount.current = true;
  }
}, [])

额外优化建议

  • 避免使用数组索引作为key,建议使用笔记的id作为key,提升渲染性能并避免潜在的列表渲染问题:
    {notes.map(note => <NoteArea key={note.id} note={note}/>)}
    
  • 可以给每个请求添加独立的加载状态,让用户看到单条笔记的加载过程,提升交互体验。

内容的提问来源于stack exchange,提问作者Timothy Singer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:50:26