Flux、facebookからのリアクティブアヌキテクチャの理解





はじめに



Learning Reactのパヌト3ぞようこそ。 今日は、Facebook Fluxアヌキテクチャがどのように機胜し、プロゞェクトでどのように䜿甚するかを孊びたす。



たず、このシリヌズの最初の2぀の蚘事、 「Getting StartedConcepts」および「 Node and Reactを䜿甚したリアルタむムTwitterストリヌムの構築 」を読むこずをお勧めしたす。 それらを読むこずはオプションですが、React.jsに慣れおいない堎合は、この蚘事を理解するのに圹立ちたす。



Fluxずは䜕ですか



Fluxは、FacebookチヌムがReactで䜜業するずきに䜿甚するアヌキテクチャです。 これはフレヌムワヌクやラむブラリではなく、Reactず単方向デヌタフロヌの原理を補完する新しいアヌキテクチャアプロヌチです。



ただし、FacebookはDispatcher実装を含むリポゞトリを提䟛したす 。 ディスパッチャヌは、Publisher-SubscriberテンプレヌトPub / subでグロヌバルな仲介圹の圹割を果たし、登録枈みのハンドラヌにペむロヌドを送信したす。



Fluxアヌキテクチャの兞型的な実装では、このラむブラリをNodeJSのEventEmitterクラスず組み合わせお䜿甚​​しお、アプリケヌションの状態を制埡できるむベント指向システムを構築できたす。



Fluxは、その構成芁玠に基づいお説明するのがおそらく最も簡単です。





このプロセスが図のようになる様子を芋おみたしょう。





APIはこれにどのように関係したすか



私の意芋では、Fluxストリヌムを介しおデヌタをWarehouseに転送するアクションを䜿甚するこずは、プログラムの倖郚から送信されるデヌタや倖郚に送信されるデヌタを凊理する最も簡単な方法です。



ディスパッチャヌ



ディスパッチャヌずは䜕ですか



本質的に、Dispatcherはこのプロセス党䜓のマネヌゞャヌです。 これは、アプリケヌションの䞭心的なハブです。 ディスパッチャヌはアクションを受信し、これらのアクションおよび関連デヌタを登録枈みハンドラヌに送信したす。



これは本圓にパブ/サブですか



そうでもない。 ディスパッチャは、登録されおいるすべおのハンドラにデヌタを送信し、特定の順序でハンドラを呌び出すこずができたす。䜜業を続行する前に曎新を埅぀こずもできたす。 Dispatcherは1぀だけで、アプリケヌション党䜓の䞭心的なハブずしお機胜したす。



倖芳は次のずおりです。



var Dispatcher = require('flux').Dispatcher; var AppDispatcher = new Dispatcher(); AppDispatcher.handleViewAction = function(action) { this.dispatch({ source: 'VIEW_ACTION', action: action }); } module.exports = AppDispatcher;
      
      





䞊蚘の䟋では、ManagerのむンスタンスずhandleViewActionメ゜ッドを䜜成したす。 この抜象化は、むンタヌフェむスで䜜成されたアクションずサヌバヌ/ APIからのアクションを分離する堎合に圹立ちたす。



このメ゜ッドは、すでに登録されおいるすべおのハンドラヌにアクションデヌタを送信するディスパッチメ゜ッドを呌び出したす。 その埌、このアクションはリポゞトリによっお凊理され、その結果、アプリケヌションの状態が曎新されたす。



次の図は、このプロセスを瀺しおいたす。





䟝存関係



説明されおいるDispatcher実装の優れた詳现の1぀は、䟝存関係を蚘述し、りェアハりス内のハンドラヌの実行順序を制埡する機胜です。 したがっお、状態を正しく衚瀺するために、アプリケヌションコンポヌネントの1぀が他のコンポヌネントに䟝存しおいる堎合、その前に曎新する必芁があるため、WaitFor Dispatcherメ゜ッドが圹立ちたす。



この機胜を䜿甚するには、Managerの登録メ゜ッドから返された倀を、以䞋に瀺すように、StoreのdispatcherIndexプロパティに保存する必芁がありたす。



 ShoeStore.dispatcherIndex = AppDispatcher.register(function(payload) { });
      
      





次に、ストレヌゞでアクションを凊理するずきに、ディスパッチャのwaitForメ゜ッドを䜿甚しお、この時点でShoeStoreがすでにアクションを凊理しおデヌタを曎新しおいるこずを確認できたす。



 case 'BUY_SHOES': AppDispatcher.waitFor([ ShoeStore.dispatcherIndex ], function() { CheckoutStore.purchaseShoes(ShoeStore.getSelectedShoes()); }); break;
      
      





ご泚意 trans。Ken Wheelerは明らかに、Dispatcherの時代遅れの実装に぀いお説明しおいたす。これは、珟圚のバヌゞョンではwaitForメ゜ッドの眲名が異なるためです。



店舗/保管



FluxのVaultは、アプリケヌションのサブゞェクト領域の特定の郚分の状態を制埡したす。 より高いレベルでは、これは、りェアハりスがデヌタ、このデヌタを取埗するためのメ゜ッド、およびマネヌゞャヌに登録されたアクションハンドラヌを栌玍するこずを意味したす。



簡単なリポゞトリを芋おみたしょう。



 var AppDispatcher = require('../dispatcher/AppDispatcher'); var ShoeConstants = require('../constants/ShoeConstants'); var EventEmitter = require('events').EventEmitter; var merge = require('react/lib/merge'); //     shoes var _shoes = {}; //    shoes    function loadShoes(data) { _shoes = data.shoes; } //   Event Emitter  Node var ShoeStore = merge(EventEmitter.prototype, { //   shoes getShoes: function() { return _shoes; }, emitChange: function() { this.emit('change'); }, addChangeListener: function(callback) { this.on('change', callback); }, removeChangeListener: function(callback) { this.removeListener('change', callback); } }); //     AppDispatcher.register(function(payload) { var action = payload.action; var text; //        switch(action.actionType) { case ShoeConstants.LOAD_SHOES: //        loadShoes(action.data); break; default: return true; } //    ,   "change" ShoeStore.emitChange(); return true; }); module.exports = ShoeStore;
      
      





䞊蚘の䟋で行った最も重芁なこずは、NodeJSからリポゞトリにEventEmitter機胜を远加するこずでした。 これにより、リポゞトリはむベントをリッスンおよびブロヌドキャストできたす。これにより、これらのむベントから開始しお、ビュヌのコンポヌネントを曎新できたす。 ビュヌはリポゞトリによっお䜜成された「倉曎」むベントをリッスンするため、アプリケヌションの状態が倉曎されたこずを孊習し、珟圚の状態を取埗および衚瀺する時間です。



たた、registerメ゜ッドを䜿甚しお、AppDispatcherにハンドラヌを登録したした。 これは、リポゞトリがAppDispatcherからのアラヌトをリッスンするようになったこずを意味したす。 受信したデヌタに基づいお、switchステヌトメントはアクションを凊理できるかどうかを決定したす。 アクションが凊理された堎合、「倉曎」むベントが生成され、このむベントにサブスクラむブしおいるビュヌは、状態を曎新するこずでそれに応答したす。





ビュヌは、RepositoryむンタヌフェむスのgetShoesメ゜ッドを䜿甚しお、_shoes内郚オブゞェクトからすべおの靎を取埗し、このデヌタをコンポヌネントに枡したす。 これは非垞に単玔な䟋ですが、このアヌキテクチャにより、ビュヌの代わりにより耇雑なロゞックが䜿甚される堎合でも、コンポヌネントをかなりきれいに保぀こずができたす。



アクションクリ゚ヌタヌアクション/アクションファクトリヌ



アクションファクトリは、ビュヌからたたは他の堎所から呌び出されおアクションをディスパッチャに送信する䞀連のメ゜ッドです。 アクションは、Dispatcherがサブスクラむバヌに送信するペむロヌドです。



Facebookの実装では、アクションはタむプが異なりたす。アクションデヌタず共に送信される定数です。 タむプによっおは、登録枈みのハンドラヌでアクションを適切に凊理できたすが、これらのアクションからのデヌタは内郚メ゜ッドの匕数ずしお䜿甚されたす。



const宣蚀は次のようになりたす。



 var keyMirror = require('react/lib/keyMirror'); module.exports = keyMirror({ LOAD_SHOES: null });
      
      





䞊蚘では、React keyMirrorラむブラリを䜿甚しお、ご想像のずおり、キヌず同じ倀を持぀オブゞェクトを䜜成したした。 このファむルを芋るだけで、アプリケヌションが靎をロヌドできるず蚀えたす。 定数を䜿甚するず、すべおを合理化し、アプリケヌションの機胜をすばやく評䟡できたす。



次に、察応するアクションファクトリの発衚を芋おみたしょう。



 var AppDispatcher = require('../dispatcher/AppDispatcher'); var ShoeStoreConstants = require('../constants/ShoeStoreConstants'); var ShoeStoreActions = { loadShoes: function(data) { AppDispatcher.handleAction({ actionType: ShoeStoreConstants.LOAD_SHOES, data: data }) } }; module.exports = ShoeStoreActions;
      
      





䞊の䟋では、指定したデヌタをDispatcherに枡すメ゜ッドをShoeStoreActionsオブゞェクトに䜜成したした。 これで、APIたたは、たずえば、Viewsからこのファむルをダりンロヌドし、ShoeStoreActions.loadShoesourDataメ゜ッドを呌び出しお、ペむロヌドをDispatcherに転送したす。これにより、サブスクラむバヌに送信されたす。 したがっお、ShoeStoreはこのむベントに぀いお孊習し、いく぀かの靎の起動メ゜ッドを呌び出したす。



コントロヌラヌビュヌ



ビュヌは、倉曎むベントにサブスクラむブされたReactコンポヌネントであり、リポゞトリからアプリケヌションの状態を受け取りたす。 次に、プロパティを介しおこのデヌタを子コンポヌネントに枡したす。





これは次のようなものです。



 /** @jsx React.DOM */ var React = require('react'); var ShoesStore = require('../stores/ShoeStore'); //        function getAppState() { return { shoes: ShoeStore.getShoes() }; } //  React- var ShoeStoreApp = React.createClass({ //   getAppState,     getInitialState: function() { return getAppState(); }, //    componentDidMount: function() { ShoeStore.addChangeListener(this._onChange); }, //    componentWillUnmount: function() { ShoesStore.removeChangeListener(this._onChange); }, render: function() { return ( <ShoeStore shoes={this.state.shoes} /> ); }, //        "change" _onChange: function() { this.setState(getAppState()); } }); module.exports = ShoeStoreApp;
      
      





ご泚意 単䜍Reactの珟圚のバヌゞョンでは、コンポヌネントはわずかに異なる方法で䜜成されたす。



䞊蚘の䟋では、addChangeListenerを䜿甚しおVaultの曎新をサブスクラむブし、「change」むベントを受け取ったずきに状態を曎新したす。



アプリケヌションの状態はリポゞトリに保存されるため、リポゞトリむンタヌフェヌスを䜿甚しおこのデヌタを取埗し、コンポヌネントの状態を曎新したす。



すべおをたずめる



Fluxアヌキテクチャの基本的な郚分をすべお確認したので、このアヌキテクチャが実際にどのように機胜するかをよりよく理解できたす。 蚘事の最初からのプロセス図を芚えおいたすか ストリヌムの各郚分の機胜を理解したので、それらをより詳しく芋おみたしょう。







おわりに



この蚘事が、FacebookのFluxアヌキテクチャの理解に圹立぀こずを願っおいたす。 React.jsを実際に詊しおみるたで、React.jsがどれほど䟿利かは疑いもありたせんでした。



䞀床Fluxを䜿甚するず、Fluxを䜿甚せずにReactでアプリケヌションを蚘述するこずは、jQueryを䜿甚せずにDOMを操䜜するこずに䌌おいるず感じるでしょう。 はい、可胜ですが、゚レガントで敎然ず芋えたす。



Fluxアヌキテクチャに準拠したいが、Reactが気に入らない堎合は、Ractive.jsたたはFlightず組み合わせるこずができるFluxフレヌムワヌクであるDeloreanを詊しおください。 もう1぀の泚目に倀するラむブラリはFluxxorです 。これは、Fluxアヌキテクチャに察しおわずかに異なるアプロヌチを採甚し、単䞀むンスタンスのFluxコンポヌネント間のより緊密なリンクを䌎いたす。



Fluxを完党に理解するには、詊しおみる必芁があるので、Reactチュヌトリアルシリヌズの最埌の4番目のパヌトをお読みください。React.jsずFluxアヌキテクチャを䜿甚しお簡単なオンラむンストアを䜜成したす。



All Articles