处理react redux中的获取错误的最佳方法是什么
What is the best way to deal with a fetch error in react redux?
我有一个用于客户端的reducer,另一个用于AppToolbar和其他一些。。。
现在假设我创建了一个提取操作来删除客户端,如果失败,我在Clients reducer中有代码,它应该做一些事情,但我也想在AppToolbar中显示一些全局错误。
但是客户端和AppToolbar还原程序不共享相同的状态部分,我无法在还原程序中创建新操作。
那么,我应该如何显示全局错误呢?感谢
更新1:
我忘了提到我使用este devstack
更新2:我把Eric的答案标记为正确,但我不得不说,我在este中使用的解决方案更像是Eric和Dan的答案的组合。。。你只需要在你的代码中找到最适合你的。。。
如果你想有"全局错误"的概念,你可以创建一个errors
reducer,它可以监听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);
就动作创建者而言,它会根据响应调度(redux thunk)成功失败
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可以简单地管理一系列错误,但可以适当地添加/删除条目。
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;
}
}
Erik的回答是正确的,但我想补充一点,您不必为添加错误而启动单独的操作。另一种方法是使用一个reducer来处理带有error
字段的任何操作。这是个人选择和惯例的问题。
例如,来自Redux real-world
的具有错误处理的示例:
// 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 error
}
return state
}
我目前针对一些特定错误(用户输入验证)采取的方法是让我的子reducer抛出异常,在根reducer中捕获它,并将它附加到操作对象。然后我有一个redux传奇,它检查操作对象是否有错误,并在这种情况下用错误数据更新状态树。
因此:
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的逻辑(这样它就可以保护自己免受无效状态的影响)。
编写自定义中间件来处理所有与api相关的错误。在这种情况下,您的代码将更加干净。
failure/ error actin type ACTION_ERROR
export default (state) => (next) => (action) => {
if(ACTION_ERROR.contains('_ERROR')){
// fire error action
store.dispatch(serviceError());
}
}
我所做的是在每个效果的基础上集中效果中的所有错误处理
/**
* central error handling
*/
@Effect({dispatch: false})
httpErrors$: Observable<any> = this.actions$
.ofType(
EHitCountsActions.HitCountsError
).map(payload => payload)
.switchMap(error => {
return of(confirm(`There was an error accessing the server: ${error}`));
});
您可以使用axios HTTP客户端。它已经实现了拦截器功能。您可以在then或catch处理请求或响应之前拦截它们。
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);
});
- 有条件更新d3.js力图中节点的最佳方法
- 将jQuery.ech()方法转换为本地JavaScript抽象的最佳方法是什么
- 处理浮点错误的最佳方法是什么
- 从数组中删除元素的最佳方法是:javascript/jquery
- 以编程方式填充组合框道场 (1.8) 的最佳方法是什么?
- 列出没有 mysql 的元素的最佳方法是什么
- 在jquery库中重新定义方法的最佳方法
- Javascript,用vars创建对象的最佳方法
- 使用 jQuery 从 HTML 中获取某些值的最佳方法
- 在变量中保存值的最佳方法是在应用程序关闭后使用,然后使用apachecordova在android中重新启动
- 在d3.json中使用d3.csv组合多个csv文件数据输入的最佳方法是什么
- 用jasmine测试JavaScriptUI的最佳方法
- 使用javascript:在没有阻止html标记(<b>、<p>等)的情况下,阻止脚本的最佳方法
- 如果我返回表,检查 Ajax 调用是否为 200 OK的最佳方法是什么
- JavaScript - 创建可链接函数时的最佳方法是什么
- 在上下文菜单项单击上显示侧边栏/弹出窗口的最佳方法是什么
- 在 JavaScript 中获取范围的随机数的最佳方法
- 在对象类上实现 jquery 作用域的最佳方法
- 将同步函数包装到承诺中的最佳方法是什么?
- 使用 MVC 删除 JavaScript 中硬编码字符串 Asp.Net 最佳方法