learning Redux from todo[1]


## 目录

接下来要设计到以下的内容

- Actions
- action creator
- Reducers
- Store
- Data Flow
- Usage with React
- Example: Todo List


### 动作

```
Actions are payloads of information that send data from your application to your store.
They are the only source of information for the store. 
You send them to the store using store.dispatch().
```


所谓动作就是一组数据,他们从 app 发送到 store. 他们就是 store 里的数据的源头.通过` store.dispatch()` 来发送数据.


比如说这里我们定义:

```
const ADD_TODO = 'ADD_TODO'
```

接着

```
{
  type: ADD_TODO,
  text: 'Build my first Redux app'

}
```

其实` Action` 就是一个普通的javascript 对象,它必须有一个` type` 属性,用来表明它能做什么样的动作, 而这个 type 必须是一个声明为常量的字符串对象. 而且一般app 的 action 都会很多,所以可以单独把他们放在一个文件. 然后可以这样引用:

```
import { ADD_TODO, REMOVE_TODO } from '../actionTypes'
```

接下来,我们将要创建一个新的动作,用来描述用户勾选某个 todo 为完成的动作. 我们会通过` index` 来标记每一个` todo` .因为我们把他们放在` array` 里,这里只是 demo, 而真实的 app 最好有专门的逻辑用来生成找个 id.

```
{
  type: TOGGLE_TODO,
  index: 5
}
```

在这,其实每一个动作尽可能让它携带最简化的数据集. 例如, 我们通过` index` 就可以代表这个 todo对象.

```
{
  type: SET_VISIBILITY_FILTER,
  filter: SHOW_COMPLETED
}
```

`动作`我们先说到这儿,接下来说说`动作创建者`

### 动作创建者

在 Redux 中, 动作的创建者就是一个地道的函数, 用来创建并返回一个动作. 可能很容易在这里混淆`动作`和`动作创建者`.

`动作创建者`的作用就是返回一个动作:

```
function addTodo(text){
  return {
    type: ADD_TODO,
    text
  }
}
```

---

> 在传统的 Flux 架构中, 一个动作者通常在定义一个 action, 之后还有`分发`到已经注册的某个 store 里?

```
function addTodoWithDispatch(text) {
  const action = {
    type: ADD_TODO,
    text
  }
  dispatch(action)
}

```


---

而在 Redux 中不这么处理. 取而代之的是去实例化一个`分发`,然后把结果传递给这个` dispatch()`函数.

```
dispatch(addTodo(text))
dispatch(completeTodo(index))
```


或者,可以创建一个`绑定动作创建者( bound action creator)` 来自动实现动作的分发:

```
const boundAddTodo = (text) => dispatch(addTodo(text))
const boundCompleteTodo = (index) => dispatch(completeTodo(index))

```

现在可以这样使用他们:

```
boundAddTodo(text)
boundCompleteTodo(index)
```

这个分发` dispatch()` 函数可以直接通过` store.dispatch()`在` store` 里访问到, 或者直接通过` react-redux` 的`帮助类方法 connect()`, 使用` bindActionCreators()`来**自动**将这些`动作创建者`绑定到对应的` dispatch()` 函数上.

动作创建者还可以是异步的,但具有副作用.

> You can read about async actions in the advanced tutorial to learn how to handle AJAX responses and compose action creators into async control flow. 

说了这么多, 来看看全部的源码.

```
/*
 * action types
 */

export const ADD_TODO = 'ADD_TODO'
export const TOGGLE_TODO = 'TOGGLE_TODO'
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'

/*
 * other constants
 */

export const VisibilityFilters = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_COMPLETED: 'SHOW_COMPLETED',
  SHOW_ACTIVE: 'SHOW_ACTIVE'
}

/*
 * action creators
 */

export function addTodo(text) {
  return { type: ADD_TODO, text }
}

export function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

export function setVisibilityFilter(filter) {
  return { type: SET_VISIBILITY_FILTER, filter }
}
```



---

index
learning Redux from todo

- [learning Redux from todo[1]](http://qiita.com/xiangzhuyuan/items/a26e97c6cac476369e37)
- [learning Redux from todo[2]](http://qiita.com/xiangzhuyuan/items/86c5c6508e8481c2dd3a)
- [learning Redux from todo[3]](http://qiita.com/xiangzhuyuan/items/9ce23a8c9f3b26c48838)
- [learning Redux from todo[4]](http://qiita.com/xiangzhuyuan/items/c082e97c3b863602fccf)
- [learning Redux from todo[5]](http://qiita.com/xiangzhuyuan/items/4e6f61a27c068b4f33e7)