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

使用Axios Promise链式调用更新useState数组的问题

问题分析与解决方案

问题根源

你的代码存在两个核心问题,导致后续API调用失效:

  1. Promise链式调用逻辑错误:.then(axios.get(target + 'two')) 这种写法会直接立即执行第二个API请求,而非等待第一个请求完成后再执行。.then() 需要接收一个函数,只有当前Promise完成时才会触发该函数内的逻辑。
  2. 闭包捕获旧state值:setData 是异步更新操作,后续then回调中访问的data始终是getData函数初始化时的空数组,无法获取到更新后的数组长度,导致判断逻辑完全失效。

方案1:使用async/await(推荐)

这种写法逻辑清晰,更容易维护,能严格保证API顺序调用,同时避免闭包问题:

const [data, setData] = useState([])

async function getData() {
  const target = 'http://localhost:5000/api/backend/target/'
  let currentData = [...data]

  // 调用第一个API
  const res1 = await axios.get(target + 'one')
  currentData = [...currentData, ...res1.data].slice(0, 20)
  setData(currentData)
  if (currentData.length >= 20) return

  // 调用第二个API(仅当当前数据不足20条时)
  const res2 = await axios.get(target + 'two')
  currentData = [...currentData, ...res2.data].slice(0, 20)
  setData(currentData)
  if (currentData.length >= 20) return

  // 调用第三个API(仅当当前数据不足20条时)
  const res3 = await axios.get(target + 'three')
  currentData = [...currentData, ...res3.data].slice(0, 20)
  setData(currentData)
}

useEffect(() => {
  getData()
}, [])
  • 通过async/await确保每个API请求完成后再执行下一个
  • 用currentData变量跟踪最新的数组状态,避免依赖useState的异步更新
  • 每次更新后判断长度,达到20条则提前终止后续请求

方案2:修正Promise链式调用

如果偏好使用Promise链式写法,需要改用函数式更新获取最新state,并修正.then()的调用逻辑:

const [data, setData] = useState([])

function getData() {
  const target = 'http://localhost:5000/api/backend/target/'

  axios.get(target + 'one')
    .then(res1 => {
      // 用函数式更新获取最新state,并返回更新后的长度
      return new Promise(resolve => {
        setData(prev => {
          const updated = [...prev, ...res1.data].slice(0, 20)
          resolve(updated.length)
          return updated
        })
      })
    })
    .then(currentLength => {
      if (currentLength >= 20) return Promise.resolve(20)
      // 仅当数据不足20条时调用第二个API
      return axios.get(target + 'two').then(res2 => {
        return new Promise(resolve => {
          setData(prev => {
            const updated = [...prev, ...res2.data].slice(0, 20)
            resolve(updated.length)
            return updated
          })
        })
      })
    })
    .then(currentLength => {
      if (currentLength >= 20) return
      // 仅当数据不足20条时调用第三个API
      axios.get(target + 'three').then(res3 => {
        setData(prev => [...prev, ...res3.data].slice(0, 20))
      })
    })
}

useEffect(() => {
  getData()
}, [])
  • 使用setData(prev => ...)函数式更新,确保获取到最新的state值
  • 通过Promise传递每次更新后的数组长度,控制后续API是否执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:40:18