2015-03-20 2 views
4

Возьмите, например, Flux TodoMVC и предположим, что я хочу иметь две Todo-приложения рядом друг с другом.Обработка нескольких экземпляров одного и того же компонента в потоке

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

Теперь, когда вы запускаете этот пример, вы заметите, что оба Todo-листы будут синхронизированы и испускают и слушать то же действие.

Что такое канонический способ предотвратить это?

+1

Работает должным образом. Вам нужно будет изменить дизайн ... например, в магазине должно быть больше информации об источнике данных (например, идентификатор, связанный с каждым экземпляром). – WiredPrairie

+0

Не уверен, о чем я говорю ... но стоит попробовать. Добавьте атрибут ключа к элементам TodoApp: ema

+0

Вы можете либо обойти appID, как упомянутый @WiredPrairie, а затем вложить структуры данных в магазины под этим приложением, или вы можете использовать экземпляры хранилища и диспетчера и передавать эти экземпляры по мере необходимости - насколько вы считаете, это будет лучше всего работать для вашего приложения. При использовании экземпляров любой компонент, который вызывает создателя действия, нуждается в ссылке на диспетчера, и он передаст диспетчер создателю действия. – fisherwebdev

ответ

0

Я только что решил эту проблему. Мне потребовалось пару дней, чтобы понять это.

В общем, вы должны сделать свое действие и хранить его как классы, а не обычные объекты, которые могут использоваться совместно с компонентами Todo. А затем создайте экземпляр класса действия и класса хранения в каждом компоненте Todo.

Чтобы избежать влияния компонентов на друг друга, вам необходимо инкапсулировать общедоступные переменные, которые могут быть разделены различными экземплярами компонентов, такими как _todos в TodoStore.js, в ваш класс хранилища.

Затем вам нужно обернуть то, что визуализируется в 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> 
Смежные вопросы