Redux Action
Action
首先,让我们来给 action 下个定义。
Actions 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的惟一来源。用法是通过 store.dispatch()
把 action 传到 store。
添加新 todo 任务的 action 是这样的:
const ADD_TODO = 'ADD_TODO';
{
type: 'ADD_TODO',
text: 'Build my first Redux app'
}
Action 本质是 JavaScript 普通对象。我们约定,action 内使用一个字符串类型的 type
字段来表示将要执行的动作。多数情况下,type
会被定义成字符串常量。当应用规模越来越大时,建议使用单独的模块或文件来存放 action。
import { ADD_TODO, REMOVE_TODO } from '../actionTypes';
样板文件使用提醒
使用单独的模块或文件来定义 action type 常量并不是必须的,甚至根本不需要定义。对于小应用来说,使用字符串做 action type 更方便些。不过,在大型应用中最多把它们显式地定义成常量。参照 减少样板代码 获取保持代码干净的实践经验。
除了 type
字段外,action 对象的结构完全取决于你。参照 Flux 标准 Action 获取如何组织 action 的建议。
这时,我们还需要再添加一个 action type 来标记任务完成。因为数据是存放在数组中的,我们通过 index
来标识任务。实际项目中一般会在新建内容的时候生成惟一的 ID 做标识。
{
type: COMPLETE_TODO,
index: 5
}
action 中传递的数据越少越好。比如,这里传递 index
就比把整个任务对象传过去要好。
最后,再添加一个 action 类型来表示当前展示的任务状态。
{
type: SET_VISIBILITY_FILTER,
filter: SHOW_COMPLETED
}
Action 创建函数
Action 创建函数 就是生成 action 的方法。“action” 和 “action 创建函数” 这两个概念很容易混在一起,使用时最好注意区分。
在 传统的 Flux 实现中,当调用 action 创建函数时,一般会触发一个 dispatch,像这样:
function addTodoWithDispatch(text) {
const action = {
type: ADD_TODO,
text
};
dispatch(action);
}
不同的是,Redux 中的 action 创建函数是 纯函数,它没有任何副作用,只是返回 action 对象而已。
function addTodo(text) {
return {
type: ADD_TODO,
text
};
}
这让代码更易于测试和移植。只需把 action 创建函数的结果传给 dispatch()
方法即可实例化 dispatch。
dispatch(addTodo(text));
dispatch(completeTodo(index));
或者创建一个 被绑定的 action 创建函数 来自动 dispatch:
const boundAddTodo = (text) => dispatch(addTodo(text));
const boundCompleteTodo = (index) => dispatch(CompleteTodo(index));
可以这样调用:
boundAddTodo(text);
boundCompleteTodo(index);
store 里能直接通过 store.dispatch()
调用 dispatch()
方法,但是多数情况下你会使用 react-redux 提供的 connect()
帮助器来调用。bindActionCreators()
可以自动把多个 action 创建函数 绑定到 dispatch()
方法上。
源码
actions.js
/*
* action 类型
*/
export const ADD_TODO = 'ADD_TODO';
export const COMPLETE_TODO = 'COMPLETE_TODO';
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER';
/*
* 其它的常量
*/
export const VisibilityFilters = {
SHOW_ALL: 'SHOW_ALL',
SHOW_COMPLETED: 'SHOW_COMPLETED',
SHOW_ACTIVE: 'SHOW_ACTIVE'
};
/*
* action 创建函数
*/
export function addTodo(text) {
return { type: ADD_TODO, text };
}
export function completeTodo(index) {
return { type: COMPLETE_TODO, index };
}
export function setVisibilityFilter(filter) {
return { type: SET_VISIBILITY_FILTER, filter };
}
下一步
现在让我们 开发一些 reducers 来指定发起 action 后 state 应该如何更新。
高级用户建议
如果你已经熟悉这些基本概念且已经完成了这个示例,不要忘了看一下在 高级教程 中的 异步 actions,你将学习如何处理 AJAX 响应和如何把 action 创建函数组合成异步控制流。
更多建议: