Flux Standard Action
action在Flux架构中是及其重要的概念,它是应用状态变化的必要条件,所有的状态都必须通过action触发。action的角色是状态变更信息的载体,是一个object,包含一个表示action type的字段,这事Flux对action的全部要求。不同于Flux作为架构思想的宽泛要求,在实际的开发中,我们往往希望打交道的同类实物有着类似的接口/结构。
Flux Standard Action的定位是“一个用户友好的Flux action对象标准”,它希望通过规范action的格式,为通用的action工具或抽象的实现奠定基础。换句话说,如果所有的action都有着类似的结构,那么通过统一的方法创建或修改action,或者通过统一的逻辑对action进行分析与相应等,便有了存在的可能性。
FSA结构
典型的Flux Standard Action结构如下:
{ type: 'ADD_TODO',payload: { text: 'Do something.' } }
不难发现,FSA首先是一个普通的action,鼓励我们将负载信息放到payload字段中。基于这样的初步认识,了解一下它的规范。
一个action必须是一个普通的JavaScript对象,有一个type字段。
一个action可能有error字段、payload字段、Meta字段。
一个action必须不能包含除type、payload、error及Meta以外的其他字段。
type
必需字段。action的type字段标识了当前发生行为的本质特征。相同类型的行为所对应的action的type值必须是严格相等的。它往往取值为字符串常量。
payload
可选字段。可以是任意类型的数据,顾名思义,它存放当前action的“负载”内容。当error字段值为true时候,payload的值应当是一个Error对象。
error
可选字段。当取值为true时,当前action代表了某处发生了错误。
Meta
可选字段。可以是任意类型的数据。用来存放非负载内容的额外信息。在Redux项目中,典型的使用Meta的例子就是存放那些用来给middleware使用的信息,理论上Meta的内容不会影响reducer的行为。
正如前面提到的,基于相同的action结构,提取action操作的公共逻辑会更加方便,redux-actions、redux-promise等都是在FSA基础上衍生出来的action处理工具。
redux-actions
在 redux 全家桶中,可以利用 redux-actions 来创建符合 FSA 规范的Action。我们从普通的action对象讲起。
以添加一个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) 规范,需要满足如下条件:
是一个纯文本对象
只具备 type 、payload、error 和 Meta 中的一个或者多个属性。type 字段不可缺省,其它字段可缺省
若 Action 报错,error 字段不可缺省,切必须为 true
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 })原文链接:https://www.f2er.com/react/303580.html