React中使用axios请求后无法获取函数内数组值如何解决
问题原因
- 核心问题是没有遵循React的状态驱动渲染规则,普通变量+顶层异步请求的写法本身就不符合React运行逻辑:
- 组件首次执行渲染时,axios异步请求还没返回结果,此时
Countrow只有初始的[1,2,3],外层的打印、列表渲染逻辑已经同步执行完成,自然拿不到后续才push进去的217 - 普通局部变量的修改不会触发React的重渲染逻辑,就算请求返回后给数组push了新值,React感知不到数据变化,不会重新执行渲染,页面自然不会展示新内容
- 接口请求直接写在组件函数顶层,会导致组件每次重渲染都重复发起请求,引发无限请求的性能问题
- 代码存在两处低级错误:一是无意义引入了后端mssql包的方法,前端环境运行会有打包异常风险;二是ul标签闭合写法错误,写成了
<ul/>而非</ul>,会导致DOM结构错乱 - 数组索引从0开始计数,初始3个元素对应索引0、1、2,push进去的第4个值对应索引是
3,之前访问Countrow[4]本身就是取不存在的位置,自然拿不到值
- 组件首次执行渲染时,axios异步请求还没返回结果,此时
修复方案
使用React内置的useState管理需要渲染的数组数据,用useEffect包裹带副作用的接口请求,保证请求只在组件首次挂载时执行一次,请求返回后通过状态更新方法修改数据,自动触发组件重渲染:
import React ,{useState, useEffect} from 'react'; import axios from 'axios'; function Home() { // 定义响应式状态,初始值为测试用的[1,2,3] const [countRow, setCountRow] = useState([1,2,3]); // 接口请求放入useEffect,空依赖表示仅组件挂载时执行一次 useEffect(() => { axios.get("http://localhost:3001/api/countStaff").then(res => { // 不要直接修改原状态,生成新数组传入更新方法 setCountRow(prevList => [...prevList, res.data.length]); }) }, []) // 状态更新后组件自动重渲染,列表会自动包含接口返回的行数 const listInfo = countRow.map((number, index) => <li key={index}>{number}</li>); return ( <div> Hello World! <ul>{listInfo}</ul> </div> ) } export default Home
额外提示:如果你的接口
/api/countStaff本身就是为了拿表行数,不需要返回全表数据再在前端取length,直接在后端查询count值返回数字,可以大幅减少接口传输体积,性能更好。
内容的提问来源于stack exchange,提问作者Dixon Koo
相关产品推荐
相关产品推荐

