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 })