如何实现服务与组件分离?调用Axios封装接口时如何仅返回目标数据数组
问题成因
当前实现拿不到纯数据数组,本质是两个环节的实现细节疏漏:
axios.get()是异步请求方法,返回的Promise最终resolve的是完整Axios响应对象,你需要的接口返回数组实际存储在这个对象的data属性下,并非直接放在Promise返回值的顶层。- 组件里直接同步调用服务方法,拿到的只是处于Pending状态的Promise实例,根本没有等到请求完成的解析结果,直接打印自然会看到和Axios完整响应结构相关的内容。
可行改造方案
整体改造分为服务层逻辑调整、组件层异步逻辑适配两部分,完全可以保持原来的分层解耦结构,不需要把请求逻辑塞回组件里。
第一步:调整独立服务的返回逻辑
修改dCandidateService.js的实现,在请求的Promise链上直接提取需要的业务数据,让服务方法最终向外暴露的Promise直接resolve纯数据数组,代码修改如下:
import axios from 'axios' export const getAll = () => { return axios .get('https://localhost:44390/api/DCandidate') // 从完整Axios响应中解构取出业务数据后再返回 .then(response => response.data) }
批量优化提示:如果项目里所有接口的业务数据都存储在Axios响应的
data字段下,不需要在每个服务方法里重复写解构逻辑,可以给全局/项目专用的axios实例配置响应拦截器,在拦截器里直接把响应值替换为response.data,所有调用这个实例的服务方法都会自动返回纯业务数据,减少重复代码。
第二步:适配组件的异步调用逻辑
服务方法返回的是Promise对象,不能在组件函数体里直接同步赋值给变量使用,需要配合异步语法等待请求完成后再读取数据,推荐在函数组件里通过useEffect触发数据获取,匹配React的组件渲染生命周期:
修改App组件的代码如下:
import * as candidate from './services/dCandidateService' import { useEffect } from 'react' function App() { useEffect(() => { const getCandidateData = async () => { try { // 等待Promise解析完成,拿到的就是接口返回的纯数据数组 const myData = await candidate.getAll() console.log(myData) } catch (error) { // 统一捕获请求异常,避免未处理的Promise报错 console.error('候选人数据获取失败', error) } } getCandidateData() }, []) return ( <> Axios Testing </> ); } export default App;
改造完成后,服务层依然独立维护请求地址、请求配置等逻辑,组件层只需要调用对应方法就能拿到处理好的纯业务数据,不会再接触到Axios的完整响应结构。
内容的提问来源于stack exchange,提问作者Nasir
相关产品推荐
相关产品推荐

