我正在使用React和Redux构建一个站点,我有一个关于如何处理401状态响应的查询.
目前,当API报告401 HTTP状态时,通常会在我的某个操作中捕获它并发送:
return dispatch({ type: 'FETCH_MONTHLY_DATA_FAILURE', error: response.data });
相关的reducer检查HTTP状态代码,我有一些Redux中间件检查这个HTTPStatus状态值并做出相应的反应.
有没有更优雅的方式我能以一般方式处理这些错误?我正在使用Axios来处理我的HTTP请求.
添加全局响应拦截器,在发生错误时调度操作
import store from './store'; // Add a response interceptor axios.interceptors.response.use(function (response) { // Do something with response data return response; }, function (error) { // Do something with response error store.dispatch({ type: 'API_ERROR', payload: error, }) return Promise.reject(error); }); // In you reducers... reduce(state, action) { if (action.type === 'API_ERROR' && action.payload.statusCode === 401) { return { // whatever needed } } return state; }
你说 :
相关的reducer检查HTTP状态代码......
使用中间件很棒但是reducer不应该检查http状态.这将超出其目的.
从文档:
reducer作业是指定应用程序的状态如何响应变化.
你的动作创建者应该是纯粹的,所有异步代码都应该存在于其他地方.
副作用不属于减速剂
有很多方法可以做到这一点.这一切都归结为偏好.
以下是以更优雅的方式处理HTTP请求的3种方法:
选项1(最强大的一个):生成器,Sagas和异步操作的复杂链
redux-saga允许你做到这一点.我个人使用这个中间件来处理我的api调用和响应.
心理模型是一个saga就像你的应用程序中的一个单独的线程,它独自负责副作用.redux-saga是一个redux中间件,这意味着可以使用正常的redux操作从主应用程序启动,暂停和取消此线程,它可以访问完整的redux应用程序状态,并且它也可以调度redux操作.
以下是使用此选项带来的好处:
将副作用代码隔离到应用程序的单个域(sagas)
多种传奇的组成(复杂与承诺)
减少承诺样板行动
创作者纯粹更容易测试!
简化用例的实现,例如:
在大型多用户,多部门博客中,如果用户曾点击过"订阅RSS Feed"按钮,则下次用户访问具有专用RSS源的部分时,请向他/她显示建议订阅此部分的Feed.
在在线IDE中,如果用户从未使用过应用程序的特定功能,但已达到上述功能可能有用的状态,请显示引入此功能的帮助对话框.
在stackoverflow中,当用户回答问题时,OP已更改问题,因此您通知用户问题已更改且答案可能不再有效.
等等
redux-observable是另一种选择:
撰写和取消异步操作以创建副作用等.
选项2:在操作创建者中将驱动异步操作的智能放在应用程序操作中
redux-promise或redux-thunk是很好的例子.
到现在为止还挺好.我们删除了耦合,将异步逻辑分离到其他地方,并拥有一个干净的架构.但是,redux-saga更高级的功能将简化复杂的用例.
这是redux thunk的要点:
像redux-thunk或redux-promise这样的异步中间件包装了商店的dispatch()方法,并允许你发送除动作之外的其他东西,例如函数或Promises.您使用的任何中间件都可以解释您发送的任何内容,反过来,可以将操作传递给链中的下一个中间件.例如,Promise中间件可以拦截Promises并异步调度一对开始/结束动作以响应每个Promise.
选项3:通过高阶组件管理副作用
高阶组件(HOC)是JavaScript函数,它为现有组件类添加功能.正如React组件允许您向应用程序添加功能一样,高阶组件允许您向组件添加功能.你可以说它们是组件的组件.
不适合所有用例!
例子:axios,一个基于promise的HTTP客户端,用于浏览器和node.js
选项4:发电机和承诺,没有Sagas
最后但并非最不重要的是,如果您不需要某些高级功能,您仍然可以使用生成器来管理前端的异步控制流,而无需添加redux-thunk依赖项.