• Action
    • 样板文件使用提醒
  • Action 创建函数
  • 源码
    • actions.js
  • 下一步

    Action

    首先,让我们来给 action 下个定义。

    Action 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。

    添加新 todo 任务的 action 是这样的:

    1. const ADD_TODO = 'ADD_TODO'
    1. {
    2. type: ADD_TODO,
    3. text: 'Build my first Redux app'
    4. }

    Action 本质上是 JavaScript 普通对象。我们约定,action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下,type 会被定义成字符串常量。当应用规模越来越大时,建议使用单独的模块或文件来存放 action。

    1. import { ADD_TODO, REMOVE_TODO } from '../actionTypes'
    样板文件使用提醒

    使用单独的模块或文件来定义 action type 常量并不是必须的,甚至根本不需要定义。对于小应用来说,使用字符串做 action type 更方便些。不过,在大型应用中把它们显式地定义成常量还是利大于弊的。参照 减少样板代码 获取更多保持代码简洁的实践经验。

    除了 type 字段外,action 对象的结构完全由你自己决定。参照 Flux 标准 Action 获取关于如何构造 action 的建议。

    这时,我们还需要再添加一个 action index 来表示用户完成任务的动作序列号。因为数据是存放在数组中的,所以我们通过下标 index 来引用特定的任务。而实际项目中一般会在新建数据的时候生成唯一的 ID 作为数据的引用标识。

    1. {
    2. type: TOGGLE_TODO,
    3. index: 5
    4. }

    我们应该尽量减少在 action 中传递的数据。比如上面的例子,传递 index 就比把整个任务对象传过去要好。

    最后,再添加一个 action type 来表示当前的任务展示选项。

    1. {
    2. type: SET_VISIBILITY_FILTER,
    3. filter: SHOW_COMPLETED
    4. }

    Action 创建函数

    Action 创建函数 就是生成 action 的方法。“action” 和 “action 创建函数” 这两个概念很容易混在一起,使用时最好注意区分。

    在 Redux 中的 action 创建函数只是简单的返回一个 action:

    1. function addTodo(text) {
    2. return {
    3. type: ADD_TODO,
    4. text
    5. }
    6. }

    这样做将使 action 创建函数更容易被移植和测试。

    在 传统的 Flux 实现中,当调用 action 创建函数时,一般会触发一个 dispatch,像这样:

    1. function addTodoWithDispatch(text) {
    2. const action = {
    3. type: ADD_TODO,
    4. text
    5. }
    6. dispatch(action)
    7. }

    不同的是,Redux 中只需把 action 创建函数的结果传给 dispatch() 方法即可发起一次 dispatch 过程。

    1. dispatch(addTodo(text))
    2. dispatch(completeTodo(index))

    或者创建一个 被绑定的 action 创建函数 来自动 dispatch:

    1. const boundAddTodo = text => dispatch(addTodo(text))
    2. const boundCompleteTodo = index => dispatch(completeTodo(index))

    然后直接调用它们:

    1. boundAddTodo(text);
    2. boundCompleteTodo(index);

    store 里能直接通过 store.dispatch() 调用 dispatch() 方法,但是多数情况下你会使用 react-redux 提供的 connect() 帮助器来调用。bindActionCreators() 可以自动把多个 action 创建函数 绑定到 dispatch() 方法上。

    Action 创建函数也可以是异步非纯函数。你可以通过阅读 高级教程 中的 异步 action章节,学习如何处理 AJAX 响应和如何把 action 创建函数组合进异步控制流。因为基础教程中包含了阅读高级教程和异步 action 章节所需要的一些重要基础概念, 所以请在移步异步 action 之前, 务必先完成基础教程。

    源码

    actions.js

    1. /*
    2. * action 类型
    3. */
    4. export const ADD_TODO = 'ADD_TODO';
    5. export const TOGGLE_TODO = 'TOGGLE_TODO'
    6. export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'
    7. /*
    8. * 其它的常量
    9. */
    10. export const VisibilityFilters = {
    11. SHOW_ALL: 'SHOW_ALL',
    12. SHOW_COMPLETED: 'SHOW_COMPLETED',
    13. SHOW_ACTIVE: 'SHOW_ACTIVE'
    14. }
    15. /*
    16. * action 创建函数
    17. */
    18. export function addTodo(text) {
    19. return { type: ADD_TODO, text }
    20. }
    21. export function toggleTodo(index) {
    22. return { type: TOGGLE_TODO, index }
    23. }
    24. export function setVisibilityFilter(filter) {
    25. return { type: SET_VISIBILITY_FILTER, filter }
    26. }

    下一步

    现在让我们 开发一些 reducers 来说明在发起 action 后 state 应该如何更新。