React 實踐記錄 04 Flux demo


Introduction

flux應用架構如下圖所示,本文並不是講述怎么立即做一個酷炫的應用,而是講述如何依照這種框架,來進行代碼的組織。

我們先把這個流程轉述為文字:拋開與webAPI的交互不談,以后的文章再介紹。
flux應用的數據流是單向的,從我們之前最熟悉的React組件看起,它們構成了上圖中的React Views。用戶交互可以使得Action Creators創建Action,交由Dispatcher分發。根據已注冊的Store信息,Dispathcer管理依賴,完成分發,而Store會觸發數據改變的事件,偵聽該事件的React Views即會進行Store Queries,拿到數據。
本文以完成下圖的功能為例,一個可以添加item的表單。如果不套flux用的代碼少的多,但是,這樣的例子適合用於講解flux而非專注於其它細節(復雜應用將更偏重於React 組件的設計,於本文中心偏離)。

源碼已經上傳:https://github.com/EcutDavid/fluxDemo

搭建目錄,文件結構

 mkdir script && cd script 
 mkdir actions components dispatcher stores constants
 cd ..
 touch entry.js index.html webpack.config.js

關於webpack,博主的webpack系列文章已經介紹,再此,不再贅述。
安裝moudles(關於moudles的選型,仁者見仁,智者見智,無需拘束於以下的例子)。

npm init 
npm install babel-loader css-loader style-loader flux react keymirror events obejct-assign --save

Dispatcher

flux中, Dispatcher是單例的,所以,直接向下面代碼一樣返回一個實例。之后,Action與Store都會用到它們。

script/dispatcher/dispatcher.js

var Dispatcher = require('flux').Dispatcher;

module.exports = new Dispatcher();

Action

實現一個枚舉,用於定義所有的Action類型,借助於keymirror實現

script/constants/appConstants.js

var keyMirror = require('keymirror');

module.exports = new keyMirror({
  CREATE: null
});

ActionCreator要借助dispatcher來分發action。

script/actions/appActionCreator.js

"use strict"

var dispatcher = require('../dispatcher/dispatcher');
var appConstants = require('../constants/appConstants');

var appActionCreator = {
  create: function(text) {
    dispatcher.dispatch({
      actionType: appConstants.CREATE,
      text: text
    });
  }
};

module.exports = appActionCreator;

Store

Store中,我們需要向dispatcher注冊並處理dispatcher分發過來的action,提供接口使得view可以偵聽數據變化,查詢數據。

script/stores/appStore.js

"use strict"
var dispatcher = require('../dispatcher/dispatcher');
var EventEmitter = require('events').EventEmitter;
var appConstants = require('../constants/appConstants');
var assign = require('object-assign');

var CHANGE_EVENT = 'change';
var textList = [];

var appStore = assign({}, EventEmitter.prototype, {
  create: function(text){
    textList.push(text);
  },
  getAll: function() {
    return textList;
  },
  emitChange: function() {
    this.emit(CHANGE_EVENT);
  },
  addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
  },
  removeChangeListener: function(callback) {
    this.removeListener(CHANGE_EVENT, callback);
  }
});

dispatcher.register(function(action) {
  switch(action.actionType) {
    case appConstants.CREATE:
      appStore.create(action.text);
      appStore.emitChange();
      break;
    default:
  }
});

Views

在view中,我們偵聽store的數據變化,在用戶交互時,發出action。

"use strict"
var React = require('react');
require('../../style/main.css');
var appActionCreator = require('../actions/appActionCreator');
var appStore = require('../stores/appStore');

var App = React.createClass({
  componentDidMount: function(){
    appStore.addChangeListener(this._onChange);
  },
  componentWillUnmount: function(){
    appStore.removeChangeListener(this._onChange);
  },
  _onChange: function(){
    var arr = appStore.getAll();
    this.setState({'infoList': arr});
  },
  getInitialState:function(){
    var arr = appStore.getAll();
    return({'infoList': arr});
  },
  add: function(){
    appActionCreator.create(React.findDOMNode(this.refs.textArea).value);
  },
  render: function(){
    var textList = this.state.infoList.map(function(item){
      return <p>{item}</p>;
    });
    return(
      <div className="container">
        <input ref="textArea" type="text"></input>
        <button className="button" onClick={this.add}>add</button>
        {textList}
      </div>
    );
  }
});

module.exports = App;

entry.js

var React = require('react');
var App = require('./script/components/app');

React.render(<App />, document.body);

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <script src="bundle.js"></script>
  </body>
</html>

效果:

dispatcher還可以管理sotre之間的依賴, 借助react,我們還可以開發很多易維護的前端組件。
本文是一個完整的flux應用的例子,側重的是代碼,flux的理念請看博主的其它文章 😃


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM