React系列---FSA知識

Flux Standard Action

action在Flux架構中是及其重要的概念,它是應用狀態變化的必要條件,全部的狀態都必須經過action觸發。action的角色是狀態變動信息的載體,是一個object,包含一個表示action type的字段,這是Flux對action的所有要求。不一樣於Flux做爲架構思想的寬泛要求,在實際的開發中,咱們每每但願打交道的同類實物有着相似的接口/結構。redux

Flux Standard Action的定位是「一個用戶友好的Flux action對象標準」,它但願經過規範action的格式,爲通用的action工具或抽象的實現奠基基礎。換句話說,若是全部的action都有着相似的結構,那麼經過統一的方法建立或修改action,或者經過統一的邏輯對action進行分析與響應等,便有了存在的可能性。promise

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對象。spa

error
可選字段。當取值爲true時,當前action表明了某處發生了錯誤。code

meta
可選字段。能夠是任意類型的數據。用來存放非負載內容的額外信息。在Redux項目中,典型的使用meta的例子就是存放那些用來給middleware使用的信息,理論上meta的內容不會影響reducer的行爲。對象

正如前面提到的,基於相同的action結構,提取action操做的公共邏輯會更加方便,redux-actions、redux-promise等都是在FSA基礎上衍生出來的action處理工具。接口

redux-actions

在 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) 規範,須要知足以下條件:

  • 是一個純文本對象
  • 只具有 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
})
相關文章
相關標籤/搜索