2015-04-29 4 views
1

В примере с потоком сообщений MessageSection прослушивает как ThreadStore, так и MessageStore, поэтому он отображает изменения StoreStore и еще раз, когда изменяется MessageStore. Однако, поскольку его состояние зависит от обоих, первый рендер выполняется, когда состояние не завершено.Недостаток флагов Facebook

Если мне не хватает чего-то, это не хорошо, нет?

Это только один пример, но образец повторяется.

Update: После долгого обсуждения темы здесь являются выводы:

  1. Реагировать убеждается, что render только срабатывает один раз в конце, даже если setState вызывается несколько раз.
  2. Функции getter для создания состояния будут вызываться несколько раз, но поскольку это чистые функции, они не будут вызывать ошибки, а только «небольшие» служебные данные.

Мое предложение заключается в использовании более одного магазина на реакцию компонента, который собирает все государство от всех других магазинов, координируя с ними с помощью waitFor, а затем уведомляет компонент, когда государство готово. Таким образом, нет накладных расходов и не зависит от внутренней магии Реагента. Это похоже на наличие «View Model», но нет двухсторонней привязки, и данные перемещаются в одном направлении от хранилища к компоненту.

ответ

1

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

Кроме того, несмотря на то, setState вызывается дважды (один раз для каждого события изменения), то система React синтетических событий партий множественных setState вызовов вместе в один раз рендеринг, что происходит после того, как оба действий обрабатываются.

Для доказательства этого случая, я сделал следующие изменения в проект:

diff --git a/examples/flux-chat/js/components/MessageSection.react.js b/examples/flux-chat/js/components/MessageSection.react.js 
index b803174..05bad0b 100644 
--- a/examples/flux-chat/js/components/MessageSection.react.js 
+++ b/examples/flux-chat/js/components/MessageSection.react.js 
@@ -50,6 +50,7 @@ var MessageSection = React.createClass({ 
    }, 

    render: function() { 
+ console.log("message section render"); 
    var messageListItems = this.state.messages.map(getMessageListItem); 
    return (
     <div className="message-section"> 
diff --git a/examples/flux-chat/js/stores/MessageStore.js b/examples/flux-chat/js/stores/MessageStore.js 
index 995ef39..3436a0f 100644 
--- a/examples/flux-chat/js/stores/MessageStore.js 
+++ b/examples/flux-chat/js/stores/MessageStore.js 
@@ -94,6 +94,7 @@ var MessageStore = assign({}, EventEmitter.prototype, { 
}); 

MessageStore.dispatchToken = ChatAppDispatcher.register(function(action) { 
+ console.log("message store", action.type); 

    switch(action.type) { 

diff --git a/examples/flux-chat/js/stores/ThreadStore.js b/examples/flux-chat/js/stores/ThreadStore.js 
index a73ceb3..e14f35d 100644 
--- a/examples/flux-chat/js/stores/ThreadStore.js 
+++ b/examples/flux-chat/js/stores/ThreadStore.js 
@@ -103,6 +103,7 @@ var ThreadStore = assign({}, EventEmitter.prototype, { 
}); 

ThreadStore.dispatchToken = ChatAppDispatcher.register(function(action) { 
+ console.log("thread store", action.type); 

    switch(action.type) { 

В консоли JavaScript, вы можете увидеть, что MessageSection повторно не рендеринг, пока оба действия не были обработаны.

Image

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

Помните, что золотое правило потока: Единственный способ изменить данные хранилища - это действия. Функции, выставленные в магазине, должны быть never мутировать данные - они должны быть чистыми функциями. Таким образом, вызов их более одного раза не вызовет ошибок.

+0

Неверно, что оба заканчивают обновление до того, как MessageSection получит событие изменения. Я не знаю, почему ты так говоришь. Во-вторых, я не уверен, как система синтетических событий дозируется и при каких условиях. Это когда 2 setStat достаточно близки? В-третьих, я думаю, что ментальная модель сломана, а неполное состояние не только неэффективно, но и может вызвать тонкие ошибки. – duraid

+0

@Delucia Вы правы - я думал о чем-то совсем другом. Выброс события изменения также синхронный. –

+0

@Delucia Я обновил свой ответ фактами, которые немного больше ... фактические (и включают доказательство :) –

Смежные вопросы