Elaine's Blog 朝著 senior 前進的工程師

Flux 單向資料流 學習筆記

2018-09-14

Flux 作用

  • 改善資料狀態與視圖狀態的 Data Flow
  • 讓頁面的狀態 Predictable
  • 資料流不會互相污染
  • 讓你的測試更加容易

Flux 角色

  • Action:規範所有改變資料的動作,讓你可以快速掌握整個 App 的行為
  • Dispatcher:將目前發生的行為,告知給所有已註冊的 Store
  • Store:存放資料和業務邏輯,並且只提供 getter API 讓人取得資料
  • View:根據資料渲染 UI 和傾聽使用者的操作事件

Flux 概念

  • dispatcher 是 facebook 提供的檔案(不必修改且只有一個)

初始化綁定

  • 定義 Action_Constants
  • 創建 action 提供給 dispatcher
  • store 向 dispatcher 註冊 callback
  • controll-view 向 store 註冊監聽器

流程

  • 當使用者在 view 做一些事件,例如點擊按鈕
  • 會觸發 action
  • dispatcher 會分發觸發的 action 給所有有在 dispatcher 註冊的 store 的 callback
  • store 的 callback 接受 action 之後更新自身資料,並觸發一個 change 事件,通知 view 資料已經更改了
  • view 透過監聽這個 change 事件,拿到對應的資料並 setState 更新 component

Flux API

  • register(function callback):string
    • 註冊 callback ,並 return 一個 token
  • unregister(string id): void
    • 在 register 註冊時會有一個 token,利用這個 token 來取消註冊
  • waitFor(array ids):void
    • 更改 callback 執行順序
  • dispatch(object payload):void
    • 分發 action 給有在 dispatcher 註冊的 store 的 callback
  • isDispathcer():boolean
    • return 目前是否處於在分發的狀態
var Dispatcher = new.Flux.Dispatcher();

var callback1 = function(payload){
    waitFor([token2]);
    console.log(isDispatcher());            // true
    console.log("callback1", payload);
}

var callback2 = function(payload){
    console.log("callback2", payload);
}

var token1 = Dispatcher.register(callback1);    // store
var token2 = Dispatcher.register(callback2);    // store

var payload = {                                 // action
    type: "click",
    id: "1"
};

Dispatcher.dispatch(payload);                   // action

console.log(isDispatcher());                 // false

實作 Todo

github 傳送門 - react-flux-todo

react-flux-todo
|--- index.html
|--- js
|    |---index.jsx
|    |---components
|        |---Todo.jsx
|        |---AddTodo.jsx
|        |---TodoList.jsx
|        |---TodoItem.jsx
|        |---actions
|            |---TodoActions.js
|            |---TodoActionTypes.js
|        |---dispatcher
|            |---AppDispatcher.js
|        |---stores
|            |---TodoStore.js
...

Flux Stardard Action (FSA) 規範

這是由 Redux 社群制定的《Flux 標準 Action 規範》

  1. 必須是一個 JavaScript 物件
  2. 必須有一個 type 屬性
    • type
      • 必要屬性
      • 通常是一個字符串常數
      • 用於指明發生動作的性質
  3. 可以有一個 payload, error, meta 屬性
    • payload
      • 可選屬性
      • 表示動作的有效載荷,可以是任何類型的值
      • 如果 error 屬性為 true ,那麼 payload 屬性應該是一個錯誤對象,類似於拒絕一個帶有錯誤對象的 Promise
    • error
      • 可選屬性
      • 出現錯誤的時候被設置為 true
      • 錯誤對象本身需要放置到 payload 屬性上
      • 如果 error 屬性擁有除 true 之外的其它值( undefined 或 null ),則 action 並不能被解析為錯誤
    • meta
      • 可選屬性
      • 主要用於放置一些額外的信息,並非有效載荷 payload 的一部分
  4. 不可以有以上四個之外的屬性存在

參考資料


Similar Posts

上一篇 Clean Code

下一篇 單元測試

Content