在反应堆中处理读取错误的最好方法是什么?

我有一个客户端的减速器,另一个为AppToolbar和其他一些…

现在让我们说,我创build了一个获取操作来删除客户端,如果失败,我的代码在客户端reducer应该做一些东西,但我也想在AppToolbar中显示一些全局错误。

但客户端和AppToolbar减速器不共享状态的相同部分,我不能在减速器中创build新的操作。

那么我怎么想显示全局错误呢? 谢谢

更新1:

我忘了提及我使用este devstack

更新2:我标记了埃里克的答案是正确的,但我不得不说,我在este中使用的解决scheme更像埃里克和丹的答案的组合…你只需要find什么适合你在你的代码中最好的.. 。

如果你想拥有“全局错误”的概念,你可以创build一个errors简化器,它可以监听addError,removeError等等动作。 然后,您可以在state.errors挂接到您的Redux状态树,并在适当的位置显示它们。

有很多方法可以解决这个问题,但总体思路是,全局错误/消息会使自己的reducer与<Clients /> / <AppToolbar />完全分离。 当然,如果这些组件中的任何一个都需要访问errors那么只要有需要,就可以将errors传递给它们。

更新:代码示例

下面是将“全局错误” errors传递到顶层<App />并有条件地渲染它(如果存在错误)的情况下的一个示例。 使用react-redux的connect将你的<App />组件连接到一些数据。

 // App.js // Display "global errors" when they are present function App({errors}) { return ( <div> {errors && <UserErrors errors={errors} /> } <AppToolbar /> <Clients /> </div> ) } // Hook up App to be a container (react-redux) export default connect( state => ({ errors: state.errors, }) )(App); 

而就动作创造者而言,它会根据回应调度( 重复 -成功)失败

 export function fetchSomeResources() { return dispatch => { // Async action is starting... dispatch({type: FETCH_RESOURCES}); someHttpClient.get('/resources') // Async action succeeded... .then(res => { dispatch({type: FETCH_RESOURCES_SUCCESS, data: res.body}); }) // Async action failed... .catch(err => { // Dispatch specific "some resources failed" if needed... dispatch({type: FETCH_RESOURCES_FAIL}); // Dispatch the generic "global errors" action // This is what makes its way into state.errors dispatch({type: ADD_ERROR, error: err}); }); }; } 

虽然你的reducer可以简单地pipe理一系列的错误,适当地添加/删除条目。

 function errors(state = [], action) { switch (action.type) { case ADD_ERROR: return state.concat([action.error]); case REMOVE_ERROR: return state.filter((error, i) => i !== action.index); default: return state; } } 

埃里克的答案是正确的,但我想补充说,你不必为单独的行动添加错误。 另一种方法是使用reducer来处理带有error字段的任何操作 。 这是个人select和惯例的问题。

例如,从Redux real-world例子 ,有error handling:

 // Updates error message to notify about the failed fetches. function errorMessage(state = null, action) { const { type, error } = action if (type === ActionTypes.RESET_ERROR_MESSAGE) { return null } else if (error) { return action.error } return state } 

我目前正在采取的一些具体的错误(用户inputvalidation)的方法是让我的子减速器抛出一个exception,在我的根减速器中捕获它,并将其附加到操作对象。 然后我有一个检查动作对象是否有错误的redux-saga,在这种情况下用错误数据更新状态树。

所以:

 function rootReducer(state, action) { try { // sub-reducer(s) state = someOtherReducer(state,action); } catch (e) { action.error = e; } return state; } // and then in the saga, registered to take every action: function *errorHandler(action) { if (action.error) { yield put(errorActionCreator(error)); } } 

然后把这个错误加到状态树上就像Erik所描述的那样。

我非常谨慎地使用它,但它使我不必复制reducer中合法属于的逻辑(所以它可以保护自己免受无效状态的影响)。

您可以使用axios HTTP客户端。 它已经实现了拦截器function。 你可以拦截请求或响应,然后再处理或捕获。

https://github.com/mzabriskie/axios#interceptors

 // Add a request interceptor axios.interceptors.request.use(function (config) { // Do something before request is sent return config; }, function (error) { // Do something with request error return Promise.reject(error); }); // Add a response interceptor axios.interceptors.response.use(function (response) { // Do something with response data return response; }, function (error) { // Do something with response error return Promise.reject(error); });