Action 是把数据从应用传到 store 的有效载荷 —— store 数据的唯一来源。
Action 本质上是 JavaScript 普通对象,Redux 约定 action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。
Usage
Action 一般是通过 store.dispatch() 来传给 store。下面以 Todo 示例的 ADD_TODO 为例,演示如何写好 Action。
store.dispatch({ type: 'ADD_TODO', text: 'xxx' })
但像上面这样内联创建 action,是无法重用 action type 的,而且需要重复编写同一类型 action 的生成代码。
Action creators
考虑代码的重用性,我们使用 action 创建函数来创建 action,并输出 action Type。
1 | // app/actions/index.js |
Action type in separate module
当应用规模越来越大时,建议使用单独的模块或文件来存放 action。
- 便于维护命名一致性;
- 便于维护代码:查询所有现存的 actions,查看 action 的添加,删除和修改记录;
- 便于发现拼写错误;
1 | // app/constants/ActionTypes.js |
Generating Action Creators
写简单的 action creator 很容易让人厌烦,且往往最终生成多余的样板代码。
我们可以写一个用于生成 action creator 的函数:
1 | function makeActionCreator(type, ...argNames) { |
一些工具库也可以帮助生成 action creator
Async Action Creators
实现原理
- 没有中间件:必须通过组件提供 dispatch 和 state 来实现判断是否有数据,开始加载(设置 loading 状态),加载成功和加载失败这些逻辑;
- 使用中间件 redux-thunk:直接在 action creator 返回函数的参数里获取 dispatch 和 state,便于代码重用,写出表达更清晰的、潜在的异步 action creators;
- 定制中间件:统一约定服务器端接口返回数据格式,将异步 action creator 模式泛化,大大减少重复代码;
Action Creator 命名技巧
loadData/loadDataIfNeeded: function
loadDataRequest: { type: 'LOAD_DATA_REQUEST' }
loadDataSuccess: { type: 'LOAD_DATA_SUCCESS', response }
loadDataFailure: { type: 'LOAD_DATA_FAILURE', error }
相关实现
问题
- 模板代码
- 乐观更新
- 错误处理