如何在useEffect Hook中正确调用封装API请求的辅助函数
问题原因
所有写法失效的核心原因是:async声明的函数返回值永远是Promise对象,你之前的实现没有等待异步请求完成、拿到真实返回的数组,就直接把Promise实例传给了setExpenditureItems,state里存的不是预期的列表数据,自然无法正常渲染。
你最早把请求逻辑全写在组件内能正常运行,本质是因为当时写了await axios.post(...)等待请求结果,抽离公共方法后漏掉了对getDocuments这个异步方法的await操作。
可行解决方案
1. 修正组件内useEffect的调用逻辑
只需要在调用getDocuments时加上await,等异步结果返回后再更新state即可,不需要额外用useCallback包裹,代码如下:
// 组件文件顶部先导入公共方法 import { getDocuments } from './你的辅助文件相对路径'; import { useState, useEffect } from 'react'; function ExpenditureComponent() { const [expenditureItems, setExpenditureItems] = useState([]); useEffect(() => { async function loadExpenditureData() { const filter = {"type": "Expenditure"} // 等待公共方法返回真实数组数据 const items = await getDocuments(filter); setExpenditureItems(items); } loadExpenditureData(); }, []); // 组件其余渲染逻辑 }
2. 修复公共辅助文件的潜在bug
你当前的辅助文件里在函数外定义了全局可变变量let response = '',如果多个组件同时调用getDocuments,会出现响应数据互相覆盖的竞态问题,建议把变量移到函数作用域内:
import axios from 'axios'; const financeUrl = "http://blah.blah.blah/blah"; // 删除全局的response变量,避免多调用场景下的数据污染 async function getDocuments(filter=null) { // 每次调用时在函数内部定义response,不同调用之间互不干扰 let response; if(!filter) { response = await axios.get(financeUrl); } else { response = await axios.post(financeUrl, filter); } console.log(response.data); return Array.from(response.data); } // 其余CRUD方法保持原有逻辑即可 export {getDocuments, createDocument, updateDocument, deleteDocument}
内容的提问来源于stack exchange,提问作者Chopps
相关产品推荐
相关产品推荐

