为什么使用字符串而不是直接方法调用来触发Redux存储中的操作?

时间:2016-03-29 11:49:20

标签: javascript redux react-redux

将字符串传递给Redux存储以触发操作而不是简单地在存储上指定其他方法并直接调用这些方法有什么好处?似乎后者会允许人们避免一堆ifswitch语句。例如,来自Redux文档:

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

替代方案:

const todos = {
  addTodo: function(state, action) {
    return [
      ...state,
      {
        text: action.text,
        completed: false
      }
    ]
  },

  completeTodo: function(state, action) {
    return state.map((todo, index) => {
      if (index === action.index) {
        return Object.assign({}, todo, {
          completed: true
        })
      }
      return todo
    })
  }
}

1 个答案:

答案 0 :(得分:2)

我认为主要原因可能是支持以下功能:

  

记录和重播用户会话,或通过时间旅行实施热重新加载

https://github.com/reactjs/redux/blob/master/docs/recipes/ReducingBoilerplate.md#actions

感谢@markerikson在FAQ中指出了这个条目:

  

为什么“type”应该是一个字符串,或至少可序列化?

     

与state一样,让行为可序列化可以实现Redux的几个定义功能,例如时间旅行调试,以及录制和重放动作。

您可能还会发现有关行动的可序列化的讨论很有趣:reactjs/redux#437

  

似乎后者会允许人们避免一堆ifswitch陈述。

无论如何,这很容易避免:

var actions = {
  ADD_TODO (state, action) {
    return [
      ...state,
      {
        text: action.text,
        completed: false
      }
    ]
  },

  COMPLETE_TODO (state, action) {
    return state.map((todo, index) => {
      if (index === action.index) {
        return Object.assign({}, todo, {
          completed: true
        })
      }
      return todo
    })
  },
};

function todos(state = [], action) {
  var handler = actions[action.type];
  if (handler) return handler(state, action);
  return state;
}

Redux文档中也对此进行了讨论:Reducing Boilerplate