ReactJS新手求教:如何统一管理API至公共文件/组件(类AngularJS Factory)
嘿,很高兴帮你解决这个问题!从Angular转到React,想要把API请求集中管理的思路非常合理——这其实和Angular里Factory/Service的核心逻辑一致,React里我们可以通过自定义API服务模块来实现,下面给你详细讲几种常用的方案:
方案1:纯函数式API模块(适合小型项目)
这是最简单直接的方式,把所有API请求封装成独立函数,放在单独的文件里,需要的时候导入即可。
第一步:创建API集中文件
比如在项目里新建 src/services/api.js,用你熟悉的请求库(axios或原生fetch)定义所有API:
// src/services/api.js import axios from 'axios'; // 全局配置API基础路径 const API_BASE = 'https://your-api-domain.com/v1'; // 封装API1请求 export const api1 = async (requestData) => { try { const response = await axios.post(`${API_BASE}/submit-form`, requestData); return response.data; } catch (err) { // 统一处理错误:比如日志上报、错误提示 console.error('API1 请求失败:', err); throw err; // 抛出错误让组件自行处理业务逻辑 } }; // 封装API2请求(示例GET接口) export const api2 = async (queryParams) => { const response = await axios.get(`${API_BASE}/user-list`, { params: queryParams }); return response.data; };
第二步:在组件中复用API
直接导入需要的API函数,在事件处理中调用:
import React from 'react'; import { RaisedButton } from 'material-ui'; // 假设你用Material UI import { api1 } from '../services/api'; class YourComponent extends React.Component { handleClick = async (event) => { event.preventDefault(); try { const result = await api1({ name: 'test', email: 'test@example.com' }); // 处理API返回结果 console.log('提交成功:', result); } catch (err) { // 组件层面的错误处理(比如提示用户) alert('提交失败,请稍后重试'); } }; render() { const style = { margin: 12 }; return ( <RaisedButton label="Submit" primary={true} style={style} onClick={this.handleClick} /> ); } } export default YourComponent;
方案2:类式API服务(适合中大型项目)
如果你的API需要全局配置(比如统一添加token、请求拦截器),可以用类来封装,并且做成单例模式,和Angular的Service逻辑几乎一致。
第一步:创建类式API服务
新建 src/services/ApiService.js:
// src/services/ApiService.js import axios from 'axios'; class ApiService { constructor() { // 创建axios实例,配置全局参数 this.apiInstance = axios.create({ baseURL: 'https://your-api-domain.com/v1', headers: { 'Content-Type': 'application/json' } }); // 请求拦截器:统一添加Authorization token this.apiInstance.interceptors.request.use(config => { const authToken = localStorage.getItem('auth_token'); if (authToken) { config.headers.Authorization = `Bearer ${authToken}`; } return config; }); // 响应拦截器:统一处理错误(比如401跳转登录页) this.apiInstance.interceptors.response.use( res => res.data, err => { console.error('API请求错误:', err); if (err.response?.status === 401) { window.location.href = '/login'; } return Promise.reject(err); } ); } // 定义API方法 async api1(data) { return this.apiInstance.post('/submit-form', data); } async api2(params) { return this.apiInstance.get('/user-list', { params }); } } // 导出单例实例,确保全局共用同一个服务 export default new ApiService();
第二步:在组件中使用
直接导入单例实例调用API:
import React from 'react'; import { RaisedButton } from 'material-ui'; import apiService from '../services/ApiService'; class YourComponent extends React.Component { handleClick = async (event) => { event.preventDefault(); try { const result = await apiService.api1({ name: 'test', email: 'test@example.com' }); console.log('提交成功:', result); } catch (err) { alert('提交失败,请稍后重试'); } }; render() { const style = { margin: 12 }; return ( <RaisedButton label="Submit" primary={true} style={style} onClick={this.handleClick} /> ); } } export default YourComponent;
额外优化:结合自定义Hook(函数组件场景)
如果你用的是React函数组件,可以把API调用和状态管理结合,封装成自定义Hook,让代码更简洁:
// src/hooks/useApi.js import { useState, useCallback } from 'react'; import { api1 } from '../services/api'; export const useApi1 = () => { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const callApi = useCallback(async (data) => { setLoading(true); setError(null); try { const result = await api1(data); return result; } catch (err) { setError(err); throw err; } finally { setLoading(false); } }, []); return { loading, error, callApi }; };
在函数组件中使用:
import React from 'react'; import { RaisedButton } from 'material-ui'; import { useApi1 } from '../hooks/useApi'; const YourFunctionComponent = () => { const { loading, error, callApi } = useApi1(); const handleClick = async (event) => { event.preventDefault(); try { const result = await callApi({ name: 'test', email: 'test@example.com' }); console.log('提交成功:', result); } catch (err) { alert('提交失败,请稍后重试'); } }; const style = { margin: 12 }; return ( <div> {loading && <p>提交中...</p>} {error && <p>请求出错了</p>} <RaisedButton label="Submit" primary={true} style={style} onClick={handleClick} disabled={loading} /> </div> ); }; export default YourFunctionComponent;
这些方案都能实现类似Angular Factory的集中式API管理,既保证了复用性,也让API逻辑更易维护。你可以根据项目规模和技术栈选择合适的方式~
内容的提问来源于stack exchange,提问作者IMdevs
相关产品推荐
相关产品推荐

