React中构建AJAX请求中心处理器及同一Promise多次调用then()问题
构建React独立的中央AJAX处理器(全局错误拦截+Promise链式支持)
这是一个完全贴合你需求的实现方案:基于axios打造独立于Redux的中央AJAX枢纽,既能统一拦截处理特定错误(避免重复代码),又能让发起请求的组件继续使用then()/catch()处理自身业务逻辑。
第一步:创建中央AJAX服务文件
新建ajaxService.js,作为所有请求的统一入口,这里我们用axios的拦截器来实现全局逻辑:
import axios from 'axios'; // 初始化axios实例,配置全局基础参数 const ajaxInstance = axios.create({ baseURL: '/your-api-base-url', // 替换成你的实际API根地址 timeout: 15000, // 全局超时时间 }); // 请求拦截器:统一处理请求头、token等 ajaxInstance.interceptors.request.use( (config) => { // 示例:自动添加登录token到请求头 const authToken = localStorage.getItem('auth_token'); if (authToken) { config.headers.Authorization = `Bearer ${authToken}`; } return config; }, (error) => { // 请求配置错误的全局处理 console.error('请求配置出错:', error); return Promise.reject(error); } ); // 响应拦截器:全局拦截特定错误,同时保留Promise链式调用 ajaxInstance.interceptors.response.use( (response) => { // 直接返回响应数据,让组件不用再取response.data return response.data; }, (error) => { // 全局拦截你需要统一处理的错误 if (error.response) { // 根据HTTP状态码处理不同错误 switch (error.response.status) { case 401: // 未授权:清除token+跳转登录页 localStorage.removeItem('auth_token'); window.location.href = '/login'; break; case 403: // 权限不足:全局提示 alert('抱歉,你没有执行此操作的权限'); break; case 500: // 服务器错误:全局提示 alert('服务器繁忙,请稍后再试'); break; // 可以继续添加其他需要全局拦截的状态码 } } else if (error.request) { // 网络错误:请求已发送但无响应 alert('网络连接失败,请检查你的网络设置'); } else { // 请求初始化错误 console.error('请求初始化出错:', error.message); } // 关键:必须把错误重新抛出,这样组件才能继续用catch/then处理 return Promise.reject(error); } ); // 封装常用请求方法,暴露给组件调用 export const ajaxService = { get: (url, params) => ajaxInstance.get(url, { params }), post: (url, data) => ajaxInstance.post(url, data), put: (url, data) => ajaxInstance.put(url, data), delete: (url) => ajaxInstance.delete(url), }; export default ajaxService;
第二步:在React组件中使用
组件只需导入这个服务,发起请求后依然能正常链式调用then()/catch(),处理自己的业务逻辑:
import React, { useEffect, useState } from 'react'; import ajaxService from './ajaxService'; function ProductList() { const [products, setProducts] = useState([]); useEffect(() => { // 发起GET请求 ajaxService.get('/products', { category: 'electronics' }) .then((productData) => { // 组件自己的成功处理逻辑 setProducts(productData); }) .catch((err) => { // 组件级的额外错误处理(如果全局拦截后还需要) console.log('组件自定义错误处理:', err); }); // 发起POST请求示例 // ajaxService.post('/products', { name: 'New Phone', price: 599 }) // .then((newProduct) => { // console.log('新增产品成功:', newProduct); // }); }, []); return ( <div className="product-list"> {products.map(product => ( <div key={product.id} className="product-item"> <h3>{product.name}</h3> <p>价格: ${product.price}</p> </div> ))} </div> ); } export default ProductList;
核心优势说明
- 无框架依赖:完全独立于Redux、MobX等状态管理库,只需要React环境就能用。
- 减少重复代码:通用错误逻辑(比如401跳转、网络错误提示)只需要写一次,所有请求自动复用。
- 保留Promise灵活性:全局拦截错误后依然抛出错误,组件可以根据自身需求继续处理成功/失败逻辑。
- 可扩展性强:可以轻松添加请求加载状态全局管理(配合React Context)、请求取消、请求重试等功能。
内容的提问来源于stack exchange,提问作者i.brod
相关产品推荐
相关产品推荐

