具有多个独立商店/调度员的 FLUX

Posted

技术标签:

【中文标题】具有多个独立商店/调度员的 FLUX【英文标题】:FLUX with multiple independent stores/dispatchers 【发布时间】:2016-02-03 23:21:38 【问题描述】:

我正在使用 React 和 Flux/McFly 构建一个应用程序,并且希望拥有独立的商店,但我的 McFly 操作被传递到我使用 mcFly 创建的每个商店 - 尽管我使用单独的文件来导入 mcFly 实例

/stores/msg/mcfly.js

var McFly           = require('mcfly');
,   MsgDispatcher   = new McFly()
;
module.exports = MsgDispatcher;

/stores/user/mcfly.js

var McFly       = require('mcfly')
,   UserMcFly   = new McFly()
;
module.exports = UserMcFly;

所以这应该是不同的实例,对吧? 但是他们的调度员似乎是一样的。 (?因为 'flux' 调度程序总是单例的?

当我用不同的 McFly“实例”创建不同的 Stores/ActionCreator-Pairs每个 Action 仍然会经过每个 STORE。 我知道很多人建议只有一个全局状态/存储,但恕我直言,这种方法并不适合每个项目,我讨厌这种行为。

TL;DR: 是否可以创建完全独立的商店/调度员 或者它是这样打算的吗?为什么?缺点: 性能不佳,StateObject 真的很大,如果没有必要检查更新,独立子应用程序不可能?,数据模型的规范化,.. .

如果没有单独的 Store/Dispatcher,我如何创建独立的可重复使用的独立子应用程序?

最好的问候, 史蒂夫

【问题讨论】:

误解了 store-reducer - 概念...问题没有意义...应该删除 【参考方案1】:

为什么所有商店都可以使用这些操作?您可以在每个商店中使用开关来捕获您对该商店感兴趣的操作。有时您实际上想在多个商店中收听相同的动作。

【讨论】:

问题是,'shoulUpdate' 方法(在 mixin 中)被触发,因为即使 Stores-State 没有改变,Store 也会发出更改事件。如果我的 'shouldComponentUpdate' 方法的 nextState 不等于实际状态,这将是一个问题......(这是我的第一个 react/flux 项目)我通过测试状态是否改变来捕获那个 changeevent。但这只是一个(坏的?)解决方法 也许是mixin。商店不应仅仅因为触发了操作而触发更新。尝试在 componentDidMount 中侦听存储集的替代方法。 确实有一个单例调度程序是通量模式背后的主要思想。【参考方案2】:

谢谢@Janaka Stevens 我将组件的 onChange-callback 添加到 Store 并在需要时手动触发它:

Thread.react.js

import React        from 'react';
import MsgStore     from '../stores/msg/MsgStore';
export default React.createClass(
        getInitialState:    function() 
            // returns the _msg object located in the MsgStore closure
            return MsgStore.getState()
           
    ,   onChange: function() 
            // i don't think that's the right way but it works
            this.setState(MsgStore.getState());
        
    // better than the mcFly mixin for multiple stores
    // so you have more control to which store your component listens
    ,   componentDidMount: function() 
            MsgStore.on('change', this.onChange);
        
        [ ... ]
    )
;

MsgStore

import React            from 'react';
import MsgMcFly       from './mcfly';
import MsgReducers    from './MsgReducers';
import combineReducers  from 'mcfly-combinereducers';
let combinedReducers    = combineReducers(MsgReducers)
// get _msgs per API | from DB
,   _msgs               = [
        id: 0, txt: 'test0', user: 'steve23'
    ,   id: 1, txt: 'test1', user: 'steve23'
    ,   id: 2, txt: 'test2', user: 'steve23'
    ]
;
export default MsgMcFly.createStore(
        getMsgs:    function() return _msgs; 
    ,   getState:   function() return 'msgs': _msgs 
    ,   createMsgObject:    function(msg) 
            return 
                id:         _msgs.length // dev
            ,   txt:        msg.txt
            ,   timestamp:  msg.timestamp || new Date()
            ,   user:       msg.user || 'steve' // dev
            
        
    ,  function(action) 

            // prevent the Store to fire for 'USER_' actions
            if(action.type.substr(0, 3) !== 'MSG')
                return false;

            combinedReducers(MsgStore.getMsgs(), action);

            MsgStore.emitChange();
            return true;
        
    )
;

【讨论】:

以上是关于具有多个独立商店/调度员的 FLUX的主要内容,如果未能解决你的问题,请参考以下文章

Flux - 如何处理多个商店更新相同的视图?

如何等待从另一家商店在一家商店发生的调度

没有动作和调度程序的通量?

Flux 设计模式 - 关于视图概念的歧义

React.js - 通量与全局事件总线

Flux 中的 AJAX:依赖状态更改时刷新存储