使用Axios Promise链式调用更新useState数组的问题
问题分析与解决方案
问题根源
你的代码存在两个核心问题,导致后续API调用失效:
- Promise链式调用逻辑错误:
.then(axios.get(target + 'two'))这种写法会直接立即执行第二个API请求,而非等待第一个请求完成后再执行。.then()需要接收一个函数,只有当前Promise完成时才会触发该函数内的逻辑。 - 闭包捕获旧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
相关产品推荐
相关产品推荐

