上面章節(jié)中,我們學(xué)會(huì)了使用 action 來(lái)描述“發(fā)生了什么”,和使用 reducers 來(lái)根據(jù) action 更新 state 的用法。
Store 就是把它們聯(lián)系到一起的對(duì)象。Store 有以下職責(zé):
getState()
方法獲取 state;dispatch(action)
方法更新 state;subscribe(listener)
注冊(cè)監(jiān)聽(tīng)器。再次強(qiáng)調(diào)一下 Redux 應(yīng)用只有一個(gè)單一的 store。當(dāng)需要拆分處理數(shù)據(jù)的邏輯時(shí),使用 reducer 組合 而不是創(chuàng)建多個(gè) store。
根據(jù) reducer 創(chuàng)建 store 非常容易。例如,假如應(yīng)用中只有一個(gè) todoApp
的 reducer,可以這樣寫(xiě):
import { createStore } from 'redux';
import todoApp from './reducers';
let store = createStore(todoApp);
為了提高可維護(hù)性,拆分成多個(gè) reducer,這時(shí)需要使用 combineReducers()
來(lái)把它們組合起來(lái)。
import { combineReducers, createStore } from 'redux';
import * as reducers from './reducers';
let todoApp = combineReducers(reducers);
let store = createStore(todoApp);
createStore()
的第二個(gè)參數(shù)可以設(shè)置初始狀態(tài)。這對(duì)開(kāi)發(fā)同構(gòu)應(yīng)用時(shí)非常有用,可以用于把服務(wù)器端生成的 state 轉(zhuǎn)變后在瀏覽器端傳給應(yīng)用。
let store = createStore(todoApp, window.STATE_FROM_SERVER);
創(chuàng)建好了 store 后,就可以驗(yàn)證程序是否工作。雖然還沒(méi)有界面,我們已經(jīng)可以測(cè)試更新邏輯了。
import { addTodo, completeTodo, setVisibilityFilter, VisibilityFilters } from './actions';
// 打印初始狀態(tài)
console.log(store.getState());
// 監(jiān)聽(tīng) state 更新時(shí),打印日志
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
// 發(fā)起一系列 action
store.dispatch(addTodo('Learn about actions'));
store.dispatch(addTodo('Learn about reducers'));
store.dispatch(addTodo('Learn about store'));
store.dispatch(completeTodo(0));
store.dispatch(completeTodo(1));
store.dispatch(setVisibilityFilter(VisibilityFilters.SHOW_COMPLETED));
// 停止監(jiān)聽(tīng) state 更新
unsubscribe();
可以看到 store 里的 state 是如何變化的:
可以看到,在還沒(méi)有開(kāi)發(fā)界面的時(shí)候,我們就可以定義程序的行為。而且這時(shí)候已經(jīng)可以寫(xiě) reducer 和 action 創(chuàng)建函數(shù)的測(cè)試。不需要模擬任何東西,因?yàn)樗鼈兌际羌兒瘮?shù)。只需調(diào)用一下,對(duì)返回值做斷言,寫(xiě)測(cè)試就是這么簡(jiǎn)單。
index.js
import { combineReducers, createStore } from 'redux';
import * as reducers from './reducers';
let todoApp = combineReducers(reducers);
let store = createStore(todoApp);
在創(chuàng)建 todo 應(yīng)用界面之前,我們先穿插學(xué)習(xí)一下數(shù)據(jù)在 Redux 應(yīng)用中如何流動(dòng)的。
更多建議: