在Flux中处理同一组件的多个实例

Handling multiple instances of the same component in Flux

本文关键字:实例 组件 Flux 处理      更新时间:2023-09-26

以Flux TodoMVC为例,假设我想让两个Todo应用程序相邻。

class TwoTodos extends React.Component {
  render () {
    return (
      <div>
        <TodoApp />
        <TodoApp />
      </div>
    );
  }
}

现在,当您运行这个示例时,您会注意到两个Todo列表将同步,因为两者都发出和侦听相同的操作。

防止这种情况的规范方法是什么?

我刚刚解决了这个问题。我花了几天时间才弄明白。

通常,您应该将操作和存储设置为类,而不是可以在Todo组件之间共享的普通对象。然后在每个Todo组件中创建一个操作类和存储类的实例。

为了避免组件相互影响,您需要将可以由不同组件实例共享的公共变量(如TodoStore.js中的_todos)封装到存储类中。

然后,您需要将app.js中呈现的内容封装到一个类中,并在使用该类之前创建该类的实例。

我将把关键的更改放在下面的代码中。

TodoActions.js:

var Actions = function(){
    //if you have any shared variables, just define them here, instead of outside of the class 
    this.getAction = function(){
        return TodoActions;
    } 
    var TodoActions = {...};
    ...
}
module.exports = Actions;

TodoStore.js:

//private functions
function create(text, todos){...}
function update(id, updates, todos){...}
var Store = function(){
    var _todos = {};
    this.getStore = function(){
        return TodoStore;
    }   
    var TodoStore = assign({}, EventEmitter.prototype, {...});
};
module.exports = Store;

TodoApp.react.js:

var TodoApp = React.createClass({
    Store: function(){},
    Actions: function(){},
    componentWillMount: function(){
        var store = require('path/to/TodoStore.js');
        var storeInstance = new store();
        this.Store = storeInstance.getStore();  
        var action = require('path/to/TodoActions.js');
        var actionInstance = new action();
        this.Store = actionInstance .getAction();  
        this.Store.addChangeListener(...);
    }
    //If you need to call methods in Actions, just call this.Actions.<method_name>
});    
module.exports = TodoApp;

app.js:

var TodoApp = require('./components/TodoApp.react');
window.Todo = function(){
    var todo = null; //In case you need to get/set the component
    this.use = function(elementId){
        todo = ReactDom.render(
            <TodoApp />,
            document.getElementById(elementId)
        )
    }
};

index.html:

<section id="todoapp1"></section>
<section id="todoapp2"></section>
<script>
    var todo1 = new Todo();
    var todo2 = new Todo();
    todo1.use('todoapp1');
    todo2.use('todoapp2');
</script>