# Store
在前面的章节中,我们学会了使用 [action](Actions.md) 来描述“发生了什么”,和使用 [reducers](Reducers.md) 来根据 action 更新 state 的用法。
**Store** 就是把它们联系到一起的对象。Store 有以下职责:
- 维持应用的 state;
- 提供 [`getState()`](../api/Store.md#getState) 方法获取 state;
- 提供 [`dispatch(action)`](../api/Store.md#dispatch) 方法更新 state;
- 通过 [`subscribe(listener)`](../api/Store.md#subscribe) 注册监听器;
- 通过 [`subscribe(listener)`](../api/Store.md#subscribe) 返回的函数注销监听器。
再次强调一下 **Redux 应用只有一个单一的 store**。当需要拆分数据处理逻辑时,你应该使用 [reducer 组合](Reducers.md#splitting-reducers) 而不是创建多个 store。
根据已有的 reducer 来创建 store 是非常容易的。在[前一个章节](Reducers.md)中,我们使用 [`combineReducers()`](../api/combineReducers.md) 将多个 reducer 合并成为一个。现在我们将其导入,并传递 [`createStore()`](../api/createStore.md)。
```js
import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(todoApp)
```
[`createStore()`](../api/createStore.md) 的第二个参数是可选的, 用于设置 state 初始状态。这对开发同构应用时非常有用,服务器端 redux 应用的 state 结构可以与客户端保持一致, 那么客户端可以将从网络接收到的服务端 state 直接用于本地数据初始化。
```js
let store = createStore(todoApp, window.STATE_FROM_SERVER)
```
## 发起 Actions
现在我们已经创建好了 store ,让我们来验证一下!虽然还没有界面,我们已经可以测试数据处理逻辑了。
```js
import {
addTodo,
toggleTodo,
setVisibilityFilter,
VisibilityFilters
} from './actions'
// 打印初始状态
console.log(store.getState())
// 每次 state 更新时,打印日志
// 注意 subscribe() 返回一个函数用来注销监听器
const 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(toggleTodo(0))
store.dispatch(toggleTodo(1))
store.dispatch(setVisibilityFilter(VisibilityFilters.SHOW_COMPLETED))
// 停止监听 state 更新
unsubscribe()
```
可以看到 store 里的 state 是如何变化的:
<img src='http://i.imgur.com/zMMtoMz.png' width='70%'>
可以看到,在还没有开发界面的时候,我们就可以定义程序的行为。而且这时候已经可以写 reducer 和 action 创建函数的测试。不需要模拟任何东西,因为它们都是[纯函数](../introduction/ThreePrinciples.md#使用纯函数来执行修改)。只需调用一下,对返回值做断言,写测试就是这么简单。
## 源码
#### `index.js`
```js
import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(todoApp)
```
## 下一步
在创建 todo 应用界面之前,我们先穿插学习一下[数据在 Redux 应用中如何流动的](DataFlow.md)。
- 自述
- 介绍
- 动机
- 核心概念
- 三大原则
- 先前技术
- 学习资源
- 生态系统
- 示例
- 基础
- Action
- Reducer
- Store
- 数据流
- 搭配 React
- 示例:Todo List
- 高级
- 异步 Action
- 异步数据流
- Middleware
- 搭配 React Router
- 示例:Reddit API
- 下一步
- 技巧
- 配置 Store
- 迁移到 Redux
- 使用对象展开运算符
- 减少样板代码
- 服务端渲染
- 编写测试
- 计算衍生数据
- 实现撤销重做
- 子应用隔离
- 组织 Reducer
- Reducer 基础概念
- Reducer 基础结构
- Reducer 逻辑拆分
- Reducer 重构示例
- combineReducers 用法
- combineReducers 进阶
- State 范式化
- 管理范式化数据
- Reducer 逻辑复用
- 不可变更新模式
- 初始化 State
- 结合 Immutable.JS 使用 Redux
- 常见问题
- 综合
- Reducer
- 组织 State
- 创建 Store
- Action
- 不可变数据
- 代码结构
- 性能
- 设计哲学
- React Redux
- 其它
- 排错
- 词汇表
- API 文档
- createStore
- Store
- combineReducers
- applyMiddleware
- bindActionCreators
- compose
- react-redux 文档
- API
- 排错