你可能不需要 Redux

如果:

  • 用户的使用方式非常简单
  • 用户之间没有协作
  • 不需要与服务器大量交互, 也没有使用 Websocket
  • 视图层只从单一来源获取数据
    那么你不需要使用 Redux

如果你的应用有以下场景,可以考虑使用 Redux

  • 某个组件的状态,需要共享;
  • 某个状态需要在任何地方拿到;
    一个组件需要改变全局状态;
    一个组件需要改变另一个组件的状态;

Redux 的设计思想

(1) Web 应用是一个状态机,视图与状态是一一对应的。
(2) 所有的状态保存在一个对象里面

基本概念和 API

1. Store

Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store 。
生成 Store:

import { createStore } from 'redux';
const store = createStore(fn);
// createStore 函数接受另一个函数作为参数,返回新生成的 Store 对象

2. State

》 Store 对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。当前时刻的 State 可以通过 store.getState() 拿到。

import { createStore } from 'redux';
const store = createStore(fn);

const state = store.getState();

Action

Action 就是 View 发出的通知,表示 State 应该要发生变化了。
Action 是一个对象。其中的 type 属性是必须的,表示 Action 的名称。其他属性可以自由设置。

const action = {
    type: 'ADD_TODO',
    payload: 'Learn Redux'
};
// 上面代码中,Action 的名称是 ADD_TODO, 它携带的信息是字符串 Learn Redux。

Action 描述当前发生的事情。改变 State 的唯一办法,就是使用 Action。 它会运送数据到 Store。

Action Creator

View 要发送多少种消息,就会有多少种 Action。如果都手写,会很麻烦。可以定义一个函数用来生成 Action, 这个函数叫做 Action Creator。

const ADD_TODO = '添加 TODO'

function addTodo(text) {
    return {
        type: ADD_TODO,
        text
    }
}
const action = addTodo('Learn Redux');
// addTodo 函数就是一个 Action Creator

store.dispatch()

store.dispatch() 是 View 发出 Action 的唯一方法。

import { createStore } from 'redux';
const store = createStore(fn);

store.dispatch({
    type: 'ADD_TODO',
    payload: 'Learn Redux'
});

// 或者结合 Action Creator
store.dispatch(addTodo('Learn Redux'));

Reducer

Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程叫做 Reducer。
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。

const reducer = function(state, action) {
    // ...
    return new_state;
}

整个应用的初始状态,可以作为 State 的默认值。

const defaultState = 0;
const reducer = (state = defaultState, action) => {
    switch(action.type) {
        case 'ADD':
            return state + action.payload;
        default:
            return state;
    }
};

const state = reducer(1, {
    type: 'ADD',
    payload: 2
});
// 实际应用中,Reducer 函数不用像上面那样手动调用,store.dispatch方***触发 Reducer 的自动执行。
import { createStore } from ''redux;
const store = createStore(reducer);
// 上面代码中,createStore 接受 Reducer 作为参数,生成一个新的 Store。以后每当 Store.dispatch 发送过来一个新的 Action,就会自动调用 Reducer,得到新的 State.

Reducer 是纯函数

Reducer 函数是一个纯函数,也就是说,只要是同样的输入,必定得到同样的输出。也就是说,同样的 state,必定得到同样的 View。正因为这一点,Reducer 函数里面不能改变 State,必须返回一个全新的对象。

// state 是一个对象
function reducer(state, action) {
    return Object.assign({}, state, { thingToChange });
    // 或者
    return {...state, ... newState};
}

// state 是一个数组
function reducer(state, action) {
    return [...state, newItem];
}

store.subscribe()

Store 允许使用 store.subscrbe 方法来监听函数,一旦 State 发生变化,就自动执行这个函数。

import { createStore } from 'redux';
const store = createStore(reducer);

store.subscribe(listener);

只要把 View 的更新函数(对于 React 项目,就是组件的 render 方法或 setState 方法)放入 listener ,就会实现 View 的自动渲染。

// store.subscribe 方法返回一个函数,调用这个函数可以解除监听
let unsubscribe = store.subscribe(() => console.log(store.getState()));

unsubscribe();