Redux如何处理reducer中的错误

时间:2017-01-24 09:38:54

标签: reactjs redux react-redux

我不确定如何处理redux reducer中的错误。当我的API提取返回数据时,我需要转换其结构并检查已在结果数据上设置的各种属性。但是,我不能在reducer中抛出错误,因为redux至少要求返回先前的状态。我该如何处理这个问题?

注意:我使用react-redux-toastr来处理错误,并且可以访问组件和操作函数中的错误调度程序。

减速器/对象search.js:

case "FETCH_OBJECTS_FULFILLED": {
  // munge data into expected format

  const _allObjects = [];
  const data = action.payload;

  // if can't find the surveys property
  if (!data.hasOwnProperty("surveys")) {

    // - - How do I handle this within the reducer? - - 

    // this.handleAlert("error", "ERROR", " Cannot find a list of surveys. Please contact support.");
    return {
      ...state,
      fetching: false
    }
  }

  // transform data (omitted for brevity's sake)

  return {
    ...state,
    fetching: false,
    fetched: true,
    options: _allObjects,
    surveys: data.surveys.map(survey => survey.name)
    // toastrs: [newToastr, ...state.toastrs]
  };

}

在ObjectSearch组件中连接后,我确实尝试更新ObjectSearch reducer中商店的toastr片段:

减速器/ index.js:

 const rootReducer = combineReducers({
    toastr: toastrReducer,
    ObjectSearch 
 });

components / object-search.js

@connect(store => {
  return {
     fetching: store.ObjectSearch.fetching,
     fetched: store.ObjectSearch.fetched,
     ready: store.ObjectSearch.ready,
     surveys: store.ObjectSearch.surveys,
     toastrs: store.toastr.toastrs
   };
 })

然而,将以下内容添加到reducers / object-search.js:似乎更新了ObjectSearch.toastrs而不是toastr.toastrs :(

  const toastrs = [...state.toastr];
  const newToastr = {
     id: guid(),
     type: 'light',
     title: 'OBJECT SEARCH ERROR',
     message: 'No Data. Please contact support.',
     options: {
       ...REDUX_TOASTR_OPTIONS,
       icon: icons.ERROR_ICON,
       status: 'error'
     }
   };
  toastrs.push(newToastr);

我是反应/减少新手,所以对此应用程序结构的任何帮助都将不胜感激!

1 个答案:

答案 0 :(得分:4)

一般模式是返回指示发生错误的状态。例如,在TODO APP的上下文中,如果收到的操作不正确,那么您可以使用以下内容:

function reducer (state = { todos: [], error: null }, action) {

   switch (action.type) {

       case "ADD_TODO":
           if (typeof action.todo === "string") {

                return Object.assign({}, state, {
                    error: {
                        code: "INVALID TODO ACTION",
                        message: "The todo action received was empty, need a .text property",
                        action
                    }
                 });

           } else {

               return { todos: [action.text, ...state.todos], error: null }

           }

   }

}

然后,无论听到商店的哪个订阅者,在看到返回的新状态后都可以采取行动。

我认为重要的是一切都是非常具体的,在reducer逻辑中,你声明状态相对于接收到的动作的行为。与外界/背景无关(该功能被认为是纯粹的)。抛出一个错误,或者在外面调用一些东西会破坏模式。

有趣的是,您可以让中间件监视具有非空错误密钥的状态,并对此采取措施。

你可能会全神贯注的另一件事是当你的行为出现真正的错误时:对象的形状是意外的,或者你有一个字符串而不是一个错误等......在这种情况下你可能会有一个意想不到的错误错误抛出。会发生什么?

您可以在source中看到redux没有做任何事情。它只会重置为 notDispatching 状态。因此,如果你没有变异状态,一切都还可以(无论如何都可以)。如果你这样做,那么你手上就会有一种不稳定的状态......