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

Why use strings rather than direct method calls to trigger an action in a Redux store?

将字符串传递给 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
    })
  }
}

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

record and replay user sessions, or to implement hot reloading with time travel

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

感谢@markerikson 在 FAQ 中指出此条目:

Why should "type" be a string, or at least serializable?

As with state, having actions be serializable enables several of Redux's defining features, such as time travel debugging, and recording and replaying actions.

您可能还会发现有关操作可串行化的讨论很有趣:reactjs/redux#437

Seems like the latter would allow one to avoid a bunch of if or switch statements.

这很容易避免:

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