action在Flux架构中是及其重要的概念,它是应用状态变化的必要条件,全部的状态都必须经过action触发。action的角色是状态变动信息的载体,是一个object,包含一个表示action type的字段,这是Flux对action的所有要求。不一样于Flux做为架构思想的宽泛要求,在实际的开发中,咱们每每但愿打交道的同类实物有着相似的接口/结构。redux
Flux Standard Action的定位是“一个用户友好的Flux action对象标准”,它但愿经过规范action的格式,为通用的action工具或抽象的实现奠基基础。换句话说,若是全部的action都有着相似的结构,那么经过统一的方法建立或修改action,或者经过统一的逻辑对action进行分析与响应等,便有了存在的可能性。promise
典型的Flux Standard Action结构以下:架构
{ type: 'ADD_TODO', payload: { text: 'Do something.' } }
不难发现,FSA首先是一个普通的action,鼓励咱们将负载信息放到payload字段中。基于这样的初步认识,了解一下它的规范。函数
type
必需字段。action的type字段标识了当前发生行为的本质特征。相同类型的行为所对应的action的type值必须是严格相等的。它每每取值为字符串常量。工具
payload
可选字段。能够是任意类型的数据,顾名思义,它存放当前action的“负载”内容。当error字段值为true时候,payload的值应当是一个Error对象。spa
error
可选字段。当取值为true时,当前action表明了某处发生了错误。code
meta
可选字段。能够是任意类型的数据。用来存放非负载内容的额外信息。在Redux项目中,典型的使用meta的例子就是存放那些用来给middleware使用的信息,理论上meta的内容不会影响reducer的行为。对象
正如前面提到的,基于相同的action结构,提取action操做的公共逻辑会更加方便,redux-actions、redux-promise等都是在FSA基础上衍生出来的action处理工具。接口
在 redux 全家桶中,能够利用 redux-actions 来建立符合 FSA 规范的Action。咱们从普通的action对象讲起。ip
以添加一个todo的Action为例:
{ type:'add_todo', data:'我要去跑步' }
这样就定义了一个添加一条todo的Action,而后就能经过某个行为去触发这个Action,由这个Action携带的数据(data)去更新store(state/reducer):
store.dispatch({ type:'add_todo', data:'your data' })
type 是一个常量,Action的必备字段,用于标识该Action的类型。在项目初期,这样定义Action也能愉快的撸码,可是随着项目的复杂度增长,这种方式会让代码显得冗余,由于若是有多个行为触发同一个Action,则这个Action要写屡次;同时,也会形成代码结构不清晰。于是,得更改建立Action的方式:
const ADD_TODO = 'add_todo'; let addTodo = (data='default data') => { return { type: ADD_TODO, data: data } } //触发action store.dispatch(addTodo());
更改以后,代码清晰多了,若是有多个行为触发同一个Action,只要调用一下函数 addTodo 就行,并将Action要携带的数据传递给该函数。相似 addTodo 这样的函数,称之为 Action Creator。Action Creator 的惟一功能就是返回一个Action供 dispatch 进行调用。
可是,这样的Action Creator 返回的Action 并非一个标准的Action。在Flux的架构中,一个Action要符合 FSA(Flux Standard Action) 规范,须要知足以下条件:
payload 是一个对象,用做Action携带数据的载体。因此,上述的写法能够更改成:
let addTodo = (data='default data') => { return { type: ADD_TODO, payload: { data } } }
在 redux 全家桶中,能够利用 redux-actions 来建立符合 FSA 规范的Action:
import {creatAction} from 'redux-actions'; let addTodo = creatAction(ADD_TODO) //same as let addTodo = creatAction(ADD_TODO,data=>data)
能够采用以下一个简单的方式检验一个Action是否符合FSA标准:
let isFSA = Object.keys(action).every((item)=>{ return ['payload','type','error','meta'].indexOf(item) > -1 })