codecamp

Redux Store

Store

上面章节中,我们学会了使用 action 来描述“发生了什么”,和使用 reducers 来根据 action 更新 state 的用法。

Store 就是把它们联系到一起的对象。Store 有以下职责:

再次强调一下 Redux 应用只有一个单一的 store。当需要拆分处理数据的逻辑时,使用 reducer 组合 而不是创建多个 store。

根据 reducer 创建 store 非常容易。例如,假如应用中只有一个 todoApp 的 reducer,可以这样写:

import { createStore } from 'redux';
import todoApp from './reducers';

let store = createStore(todoApp);

为了提高可维护性,拆分成多个 reducer,这时需要使用 combineReducers() 来把它们组合起来。

import { combineReducers, createStore } from 'redux';
import * as reducers from './reducers';

let todoApp = combineReducers(reducers);
let store = createStore(todoApp);

createStore() 的第二个参数可以设置初始状态。这对开发同构应用时非常有用,可以用于把服务器端生成的 state 转变后在浏览器端传给应用。

let store = createStore(todoApp, window.STATE_FROM_SERVER);

发起 Actions

创建好了 store 后,就可以验证程序是否工作。虽然还没有界面,我们已经可以测试更新逻辑了。

import { addTodo, completeTodo, setVisibilityFilter, VisibilityFilters } from './actions';

// 打印初始状态
console.log(store.getState());

// 监听 state 更新时,打印日志
let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
);

// 发起一系列 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));

// 停止监听 state 更新
unsubscribe();

可以看到 store 里的 state 是如何变化的:

可以看到,在还没有开发界面的时候,我们就可以定义程序的行为。而且这时候已经可以写 reducer 和 action 创建函数的测试。不需要模拟任何东西,因为它们都是纯函数。只需调用一下,对返回值做断言,写测试就是这么简单。

源码

index.js

import { combineReducers, createStore } from 'redux';
import * as reducers from './reducers';

let todoApp = combineReducers(reducers);
let store = createStore(todoApp);

下一步

在创建 todo 应用界面之前,我们先穿插学习一下数据在 Redux 应用中如何流动的

Redux Reducer
Redux 数据流
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }