React入門與進階之Flux

wmdk3776 8年前發布 | 6K 次閱讀 前端技術 React Flux

React入門與進階之Flux

本篇我們詳細介紹為React設計的架構模式Flux。Flux為React提供了一種單向數據流模式,使用此模式能夠很方便的監控數據變化的原因和過程。

Flux初識

Flux是非死book用來創建客戶端web應用的一種架構模式,它使用單向數據流方式實現了React組件的復合和通信。

一個Flux應用主要包含三大部分:dispatcher,store和views(即React Component)。如果細分一下,也可以分為四部分:dispatcher,action,store和views。Flux模式下各部分均相互獨立。

數據流

貫穿Flux的一個核心概念是單向數據流(undirectional data flow),盜個官方圖:

如圖,Flux各部分相互獨立,使用Action creators輔助函數創建一個action,提供給dispatcher;在store中給dispatcher注冊回調函數,dispatcher通過回調函數將每個action分發給所有store;store根據action進行更新操作,并發布特定變化事件,views訂閱該特定變化事件,并注冊回調函數;特定變化事件觸發后回調函數執行,該函數可以接收數據參數并將數據傳遞給React組件,調用setState()方法,整個組件進行重新渲染。

Action

Action creator是一個輔助函數,該輔助函數創建一個action,且將該action傳遞給dispatcher;該函數接收一個對象參數,該對象擁有type屬性,表示所創建action的類型,也可以包含其他數據。

dispatcher提供一個方法,允許我們觸發一個dispatch,該方法接收一個對象做參數,隨后將這個對象分發給所有store,我們把該對象叫做action,此方法就是我們通常說的action creator。

var NotingDispatcher = require('../dispatcher/NotingDispatcher');
    var _CONSTANT = require('../commons/variables');
    var NotingActions = {
        create: function(content) {
            NotingDispatcher.dispatch({
                type: _CONSTANT.CREATE,
                content: content
            });
        }
    };

代碼中,使用dispatcher提供的dispatch方法,創建一個action給dispatcher,該action對象有type屬性代表action類型,也可以有其他任何屬性,如此處的noting內容屬性。

Dispatcher

Dispatcher提供一個register方法,該方法允許我們為該dispatcher注冊一個回調函數,該回調函數接收一個action參數,在回調中將action傳遞給store。

Diapatcher還提供一個dispatch方法,在action中觸發注冊的回調函數。

dispatcher是Flux應用管理數據流的中心線。

注:dispatcher允許我們將每一個action分發給所有store。

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

對于dispatcher,我們只需要使用Flux提供的Dispatcher;

Store

store主要負責給dispatcher注冊回調函數,在回調函數中根據傳入的action進行相應處理,更新store(更新應用狀態),并發布一個變化事件,該事件在views中觸發對該事件的訂閱,可以通過事件回調函數將新的應用狀態作為參數傳入views。

在Flux應用中,我們在store內維護應用狀態和邏輯。

注:store中的應用狀態不是React組件中所說的state。

發布訂閱模式

Flux store中使用發布訂閱模式維護,傳遞應用狀態,這里使用events模塊提供發布訂閱功能的實現。

    var EventEmitter = require('events').EventEmitter;
    var NotingDispatcher = require('../dispatcher/NotingDispatcher');
    var Utils = require('../commons/utils');
    var notings = require('../commons/NotingData');
    var _CONSTANT = require('../commons/variables');

var NotingStore = Utils.extend({}, EventEmitter.prototype, {
    create: function(content) {
        var id = Utils.makeUID();
        notings[id] = {
            id: id,
            content: content
        };
    },
    getAllNotings: function() {
        return notings;
    },
    emitChange: function() {
        this.emit(_CONSTANT.CHANGEEVENT);
    },
    bindChangeEvent: function(callback) {
        this.on(_CONSTANT.CHANGEEVENT, callback);
    },
    removeChangeEvent: function(callback) {
        this.removeListener(_CONSTANT.CHANGEEVENT, callback);
    }
});

NotingDispatcher.register(function(action) {
    var content = action && action.content;

    switch(action.type) {
        case _CONSTANT.CREATE:
            if (content !== '') {
                NotingStore.create(content);
                NotingStore.emitChange();
            } 
            break;
    }
});</code></pre> 

在store中,我們使用dispatcher提供的register方法為dispatcher注冊回調函數,回調函數接收一個action,根據action類型和數據做相應的邏輯處理。我們也可以看到,整個應用的狀態(主要指數據)在store中進行維護,并通過發布/訂閱模式結合回調函數的方式將應用狀態的更新發布到views,使得views能將數據傳遞給React組件樹,改變組件狀態。

Views

Flux中的views負責在組件渲染后監聽(訂閱)由store發布的變化事件,在事件回調中,新的數據作為參數傳入,然后調用React組件的setState()方法,更新組件狀態,觸發組件的重新渲染。

views從store接收數據并將數據傳給組件樹,組件樹根據傳入的數據更新state。

注:Flux的views是一種特殊的控制視圖(control-views)。

    var React = require('react');
    var NotingStore = require('../stores/NotingStore');
    var NotingList = require('./NotingList');

    function getNotingState() {
        console.log(NotingStore.getAllNotings());
        return {
            notings: NotingStore.getAllNotings()
        };
    }

    var NotingApp = React.createClass({
        _onChange: function() {
            this.setState(getNotingState());
        },
        getInitialState: function() {
            return getNotingState();
        },
        componentDidMount: function() {
            NotingStore.bindChangeEvent(this._onChange);
        },
        componentWillUnMount: function() {
            NotingStore.removeChangeEvent(this._onChange);
        },
        render: function() {
            return (
                <div>
                    <h2>React Noting</h2>
                    <NotingList notings={this.state.notings}></NotingList>
                </div>
            );
        }
    });

如代碼中,在組件生命周期函數componentDidMount即組件渲染完成后觸發訂閱stor管理的變化事件,在組件卸載的時候取消訂閱(componentWillUnMount函數中實現)。

 

 

 

來自:http://blog.codingplayboy.com/2016/09/25/react_flux/

 

 本文由用戶 wmdk3776 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!