你可能不需要 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();