【天贏金創】React flux九淺一深

來源:互聯網
上載者:User

標籤:

這個是 Facebook 官方學習 Flux 的 todo 例子

想用這個例子來總結一下怎麼從零開始用 React 和 Flux 構建一個 App

Structure
App├─ javascripts│  ├─ actions│  │  ├─ TodoActions.js│  ├─ components│  │  ├─ TodoComponents│  │  │  ├─ TodoApp.js│  │  │  ├─ Header.js│  │  │  ├─ MainSection.js│  │  │  ├─ Footer.js│  │  │  ├─ TodoItem.js│  │  │  ├─ TodoTextInput.js│  ├─ constants│  │  ├─ TodoConstants.js│  ├─ dispatcher│  │  ├─ AppDispatcher.js│  ├─ stores│  │  ├─ TodoStore.js├─ stylesheets│  ├─ TodoStyle.css├─ index.html├─ README.md├─ package.json├─ webpack.config.js

可能你看到的這個結構和官方 demo 的結構會有點不同,那是因為官方的 demo 整個的本身只有 todo 這個功能,但實際上遠遠不至。所以在 components 下會細分是什麼部分的組件,像 TodoComponents

關於 Flux 裡的 Action, Dispatcher, Store and Controller View 這些概念如果還不瞭解的話可以去看看這兩篇文章

  • Flux For Stupid People38
  • Getting To Know Flux, the React.js Architecture25
Components

首先你通過你 app 的介面來確定你的組件,如

從這個圖我們可以看到,我們的組件有

  • Header
  • MainSection
  • Footer
  • TodoItem
  • TodoTextInput

在 MainSection 裡有 TodoTextInput 是當我們雙擊我們已經存在的 todo,可以對其進行更新

Actions

確定了組件之後,我們就可以確定我們的 TodoActions 檔案了。

對於這個 Todo app,有多少 actions 呢?

  • create - 我們可以建立一條新的 todo
  • updateText - 雙擊已經存在的 todo,可以對其進行更新
  • toggleComplete - 看到每一條前面的勾勾了嗎?就是可以給你決定是否完成了
  • toggleCompleteAll - 看到輸入框前面那個 ? 了嗎?就是讓你全部完成,或者全部不完成的
  • destroy - 看到每一條後面那個叉叉了嗎?要 hover 在上面才看到的,就是給你刪除這一條的
  • destroyCompleted - 看到 Footer 下面那個 Clear completed 了嗎?就是給我們刪除已經完成的 todo 的

就是這樣,我們根據我們的需求在這個檔案裡定義不同的 action 函數,但這裡的函數並不涉及邏輯的處理,這裡函數只是告訴我們的 Dispatcher,使用者進行了什麼操作。所以我們只需要給 Dispatcher 傳的一個對象,對象裡一個必要的屬性就是 actionType。如果使用者進行這個操作有給我們傳的參數的話。那參數也會放在這個對象裡。

例如使用者想建立一條新的 todo ,就是我們的 create action 了

import AppDispatcher from ‘../dispatcher/AppDispatcher‘; import TodoConstants from ‘../constants/TodoConstants‘; var TodoActions = {  create (text) {    AppDispatcher.dispatch({      actionType: TodoConstants.TODO_CREATE,      text: text    });  }, // other actions } export default TodoActions;

當我們執行 AppDispatcher.dispatch 這個方法,並傳給他一個有 actionType 屬性的對象時,他就會在大喊,“有人做了一個操作呀,這個操作就是 xxx (actionType 的值),還帶了個參數,你們哪個來處理一下呀”

嗯嗯,就是這樣,資料就從 Action 傳到了 Dispatcher

Dispatcher

Dispatcher 的具體實現可以看 github.com/facebook/flux/blob/master/src/Dispatcher.js

遊客只可以貼兩個連結,我也是醉

當我們用 Facebook 給我們提供的 Dispatcher,那麼一切都會變得簡單了許多

npm install --save flux
import Flux from ‘flux‘; var Dispatcher = Flux.Dispatcher; export default new Dispatcher();

Dispatcher 在整個應用

只有一個,只有一個,只有一個

有人就說了,你 Dispatcher 只負責喊的,我不要你也好像可以呀。嗯嗯,那就不叫 Fulx 了,叫 Reflux github.com/spoike/refluxjs

Constants

剛剛我們看到在我們的 Actions 裡,actionType: TodoConstants.TODO_CREATE,這個 TodoConstants 其實就是我們操作的名字,相當於一個常量,定義在 Constants 裡方便管理和調用而已。

一般你有多少個 action,就有多少個常量在這個 Constants 裡

KeyMirror 就是建立一個對象,裡面鍵的值等於鍵的名字 - -

Stores

主角登場! 但, Store 是什嗎?

Store 是一個儲存資料的地方
var _todo = {};
Store 是一個充滿邏輯的地方

所有 actions 的邏輯處理,都會在這裡發生。像我們的 create action

function create (text) { var id = (new Date() + Math.floor(Math.random() * 999999)).toString(36);  _todos[id] = {    id: id,    complete: false,    text: text  };}
Store 是一個響應 Dispatcher 呼喊的地方

“有人做了一個操作呀,這個操作就是 xxx (actionType 的值),還帶了個參數,你們哪個來處理一下呀”

在 Store 裡,我們通過 Dispatcher “註冊”了一個回呼函數,每當我們調用 dispatch 函數的時候,就是 Dispatcher 大喊的時候,我們根據不同的 actionType,來調用我們不同的邏輯處理函數,像這樣

import AppDispatcher from ‘../dispatcher/AppDispatcher‘; import TodoConstants from ‘../constants/TodoConstants‘;AppDispatcher.register((action) => { var text; switch(action.actionType) { case TodoConstants.TODO_CREATE:      text = action.text.trim(); if (text !== ‘‘) {        create(text);        TodoStore.emitChange();      } break; // other case }});
Store 是一個鞭策 Controller View 改變的地方

每當 Store 改變了資料之後,他都要 Controller View 跟著他改變。他們還約定了暗號

var CHANGE_EVENT = ‘change‘;

Store 跟 Controller View 說,我一喊 “變”,你聽到之後,你就叫你的手下一起變。

Controller View 說好。

但是 Store 不會喊,Controller View 也聽不到。

所以 Store 從 EventEmitter中學會了喊,也給 Controller View 買來了助聽器

import assign from ‘object-assign‘; var EventEmitter = require(‘events‘).EventEmitter; var TodoStore = assign({}, EventEmitter.prototype, {  areAllComplete () { for (var id in _todos) { if (!_todos[id].complete) { return false;      }    } return true;  },  getAll () { return _todos;  },  emitChange () { this.emit(CHANGE_EVENT);  },  addChangeListener (callback) { this.on(CHANGE_EVENT, callback);  },  removeChangeListener (callback) { this.removeListener(CHANGE_EVENT, callback);  }}); export default TodoStore;

所以每當執行完邏輯處理函數之後,Store 都會喊一句 TodoStore.emitChange();

助聽器 addChangeListener (callback) { this.on(CHANGE_EVENT, callback) } 也買好了,成不成功,就看 Controller View 了

Controller View

在 Components 裡,你看不到 TodoApp 這個組件,因為對於 Todo 這個 App,TodoApp 這個組件,就是 Contriller View,他掌管全部的 Components。

但是重要的是,他怎麼帶 Store 給他買的助聽器

componentDidMount () {  TodoStore.addChangeListener(this._onChange.bind(this));}

當組件渲染完成後,就綁定了 Store 的 addChangeListener,並回調了自己的 onChange 方法。

_onChange () { this.setState(this.getTodoState.bind(this)());}

Store 一喊,Controller View 聽到之後,更新所有資料,以 props 的方式傳給他的手下 - 即他掌管的 Components

Summary

現在我們來疏理一下整個流程(就 create 而言)

  1. 使用者輸入要新增的 todo,一敲斷行符號,觸發 onKeydown 方法。
  2. onKeydown 調用了 onSave 方法,onSave 調用了 TodoActions.create 方法。
  3. TodoActions.create 觸發了 AppDispatcher.dispatch 方法,AppDispatcher 大喊了一聲。
  4. TodoStore 響應,根據 actionType 調用了 create 邏輯處理函數,執行完,喊了一句 “變”。
  5. Controller View 帶著助聽器聽到了接著更新資料,把資料傳給了各個 Components。
  6. 重新渲染,新增完畢。

以上是本人淺顯的理解,如有錯誤,歡迎指正 : )

【天贏金創】React flux九淺一深

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.