Redux可以用3个基本原则来描述:

单一数据源原则(Single source of truth)

应用的整个状态存储在单例store的对象树中。

在此基础上非常便于创建通用应用,不需要经过特殊的处理,直接将服务端的状态序列化后混合到客户端状态中即可。单例的状态树使得程序理解和调试都变得非常简单,可以在开发过程中针对某个时刻的状态反复调试,促进开发的节奏。将一个应用中所有的状态都存储在一个单例树上之后,一些在传统开发模式中难以实现的功能——比如回退/前进——突然变得简单起来。

console.log(store.getState())

/* Prints
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
*/

状态只读(State is read-only)

改变状态树的唯一方式是通过派发action——一个用来描述发生情况的对象

这确保了无论是用户输入还是网络响应等交互都不能直接修改应用状态。只能通过明确的传递一个Action来表达状态修改的意图。并且所有状态修改的操作均严格按照发生的顺序集中处理,不存在其他遗漏的情况。Action就是普通对象,可以用来记录日志,序列化,存储,也可以用来重现测试或调试Bug。

store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})

store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})

纯函数更改(Changes are made with pure functions)

被称作Reducer的纯函数专门用来响应Action修改状态树。

Reducer是纯函数,接收当前状态和一个Action,并返回修改后的状态。切记是返回一个全新的状态对象,千万避免修改当前状态。创建应用可以从一个单独的Reducer开始,随着应用规模的增长,将其拆分为更小的Reducer用来分别处理状态树的各个部分。Reducer只是函数而已,可以在代码中根据需求控制其调用,传递额外的数据,也可以针对分页之类的常见任务抽象出可重用的Reducer。

function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

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
  }
}

import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)

至此,你应该知道Redux是什么了。