React调用封装async/await API组件挂载时返回undefined问题
React useEffect调用封装API方法返回undefined问题
问题描述
React开发中遇到异常现象:在useEffect对应的组件挂载逻辑中,直接使用async/await调用API接口时,可以在组件挂载时正常获取返回数据;但调用从selectApi.js文件引入的封装好的getLevels()方法时,组件挂载阶段该方法会返回undefined。
相关代码
App.js文件代码:
import axios from "axios"; import React, { useEffect, useState } from "react"; import { getLevels } from "./selectApi"; export default function App() { const [options, setOptions] = useState([]); useEffect(() => { loadLevels(); }, []); const loadLevels = async () => { // 直接在当前文件调用API可正常运行 const res = await axios.get("http://localhost:3040/v2/feedback/levels"); console.log("Data ----> ", res); // 正常打印返回数据 setOptions(res.data) /* 引入封装的getLevels调用时返回undefined getLevels().then((res) => { console.log("Data --> ", res); // 组件加载时打印 Data --> Undefined });*/ }; return ( <div className="App"> <h1>Hello Select</h1> <select> <option value="">Please select</option> {options.length > 0 && options.map((item) => ( <option key={item.id} value={item.id}> {item.name} </option> ))} </select> </div> ); }
selectApi.js文件代码:
const ENDPOINT_URL = "http://localhost:3040/v2/feedback/"; export const getLevels = async () => { await axios.get("http://localhost:3040/v2/feedback/levels"); };
直接在App.js中调用接口可正常运行


问题根源
封装的getLevels方法存在两个问题:
- 核心问题:async函数没有显式返回值。函数内仅
await了axios请求,但没有把请求结果return出去,async函数默认返回的Promise resolve值就是undefined,外部调用时拿到的结果自然为undefined。 - 遗漏依赖引入:
selectApi.js中使用了axios,但没有在文件顶部导入axios,实际运行时还会触发axios未定义的报错。
修复方案
- 修改
selectApi.js中的getLevels方法,返回请求结果,同时补上axios导入:
// 补上axios导入 import axios from "axios"; const ENDPOINT_URL = "http://localhost:3040/v2/feedback/"; export const getLevels = async () => { // 把请求结果返回出去 return await axios.get(`${ENDPOINT_URL}levels`); };
也可以简化写法,直接返回axios请求的Promise实例,不需要额外async/await包裹:
import axios from "axios"; const ENDPOINT_URL = "http://localhost:3040/v2/feedback/"; export const getLevels = () => { return axios.get(`${ENDPOINT_URL}levels`); };
- App.js中调用封装方法时,正常接收返回值即可,async/await、.then链式调用两种写法都支持:
const loadLevels = async () => { // async/await写法 const res = await getLevels(); setOptions(res.data); // 或者.then链式写法 // getLevels().then(res => { // setOptions(res.data) // }) };
修改后即可正常获取接口返回数据,和直接在组件内调用axios的效果完全一致。
内容的提问来源于stack exchange,提问作者Jonh
相关产品推荐
相关产品推荐

