React.js中GET请求后如何将接口返回值正确赋值给data变量
问题根因
你当前代码拿不到赋值结果是JS异步运行机制+React更新机制共同导致的必然结果:
api.get()是异步Promise操作,then内的逻辑会被加入微任务队列,等所有同步代码执行完、接口返回响应后才会执行。你写在请求外层的console.log(data)属于同步代码,执行时接口还没返回,data自然还是初始的空数组。- React组件内普通
let声明的变量不会被框架追踪状态变化,就算后续异步阶段给它赋了新值,组件也不会触发重渲染,视图和其他逻辑里拿不到更新后的值。
正确实现方案
React里存异步请求返回的可响应数据,必须用官方提供的状态管理API,分函数组件和类组件两种常用写法:
函数组件(React 16.8+推荐写法)
用useState存响应数据,useEffect管理组件挂载阶段的请求副作用,示例代码:
import { useState, useEffect } from 'react'; export default function DataList() { // 声明响应式状态,初始值为空数组 const [data, setData] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { // 封装异步请求函数 const loadData = async () => { try { const res = await api.get('/'); // 调用状态更新方法赋值,自动触发组件重渲染 setData(res.data); } catch (err) { console.error('请求异常:', err); } finally { setLoading(false); } }; loadData(); }, []); // 空依赖数组表示仅在组件首次挂载时执行请求 // 首次渲染时data为初始空数组,请求完成更新状态后会重新执行render,拿到最新值 return ( <div> {loading ? ( <div>数据加载中...</div> ) : ( <ul> {data.map(item => <li key={item.id}>{item.name}</li>)} </ul> )} </div> ); }
类组件写法
用类组件自带的state存储数据,setState方法触发更新,在componentDidMount生命周期里发请求:
import React from 'react'; class DataList extends React.Component { constructor(props) { super(props); this.state = { data: [], loading: true }; } componentDidMount() { api.get('/') .then(res => { this.setState({ data: res.data }); }) .catch(err => console.error('请求异常:', err)) .finally(() => { this.setState({ loading: false }); }); } render() { const { data, loading } = this.state; return ( <div> {loading ? ( <div>数据加载中...</div> ) : ( <ul> {data.map(item => <li key={item.id}>{item.name}</li>)} </ul> )} </div> ); } } export default DataList;
关键注意点
- 所有需要用到接口返回值的逻辑,必须放在请求完成的回调里:要么写在
.then()回调内部,要么写在await语法的请求语句之后,不要在请求代码的同步外层直接读取变量。 - 不要用普通
let/var/const变量存需要驱动视图更新的数据,这类变量的修改不会被React感知,不会触发页面重渲染。 - 建议搭配加载态、错误提示逻辑,避免请求过程中页面出现空白、报错。
内容的提问来源于stack exchange,提问作者isreal learsi
相关产品推荐
相关产品推荐

