Facebook流量不足
Facebook flux deficiency
在 flux-chat 示例中,MessageSection 侦听 ThreadStore 和 MessageStore,因此它在 ThreadStore 存储更改时呈现,并在 MessageStore 更改时再次呈现。但是,由于它的状态取决于两者,因此在状态未完成时完成第一次渲染。
除非我遗漏了什么,否则这不是很好,不是吗?
这只是一个示例,但该模式正在重复。
更新:经过长时间的讨论,这里是结论:
- React 确保
render
只在最后触发一次,即使 setState
被多次调用也是如此。
- 构建状态的 getter 函数将被多次调用,但由于这些是纯函数,它们不会导致错误,只会导致 'small' 开销。
我的建议是每个 React 组件最多使用一个存储,通过使用 waitFor
与它们协调从所有其他存储收集所有状态,然后在状态准备就绪时通知组件。这样就没有开销,也不依赖于 React 的内部魔法。这与 'View Model' 类似,但没有双向绑定,数据从存储到组件的单向流动。
一般情况下,这不是问题,只要每个店铺内部保持一致即可。如果商店之间存在数据依赖性,商店可以使用 waitFor
来确保数据以正确的顺序传播。
此外,即使 setState
被调用两次(每个更改事件一次),React 合成事件系统将多个 setState
调用分批处理到一个渲染中,这发生了 after 两个动作都被处理了。
为了证明这个案例,我对项目做了如下修改:
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
在两个操作都已处理之前不会重新呈现。
所以,在这种情况下,唯一的额外工作是 getStateFromStores
被调用两次而不是一次,但我相信一点点额外的开销是值得的,以利用简化的心智模型只需从任何需要更新的商店发出更改事件。
请记住,通量的黄金法则是:改变存储数据的唯一方法是通过操作。在商店中公开的函数应该 永远不会 改变数据——它们应该是纯函数。因此,多次调用它们不会导致错误。
在 flux-chat 示例中,MessageSection 侦听 ThreadStore 和 MessageStore,因此它在 ThreadStore 存储更改时呈现,并在 MessageStore 更改时再次呈现。但是,由于它的状态取决于两者,因此在状态未完成时完成第一次渲染。
除非我遗漏了什么,否则这不是很好,不是吗?
这只是一个示例,但该模式正在重复。
更新:经过长时间的讨论,这里是结论:
- React 确保
render
只在最后触发一次,即使setState
被多次调用也是如此。 - 构建状态的 getter 函数将被多次调用,但由于这些是纯函数,它们不会导致错误,只会导致 'small' 开销。
我的建议是每个 React 组件最多使用一个存储,通过使用 waitFor
与它们协调从所有其他存储收集所有状态,然后在状态准备就绪时通知组件。这样就没有开销,也不依赖于 React 的内部魔法。这与 'View Model' 类似,但没有双向绑定,数据从存储到组件的单向流动。
一般情况下,这不是问题,只要每个店铺内部保持一致即可。如果商店之间存在数据依赖性,商店可以使用 waitFor
来确保数据以正确的顺序传播。
此外,即使 setState
被调用两次(每个更改事件一次),React 合成事件系统将多个 setState
调用分批处理到一个渲染中,这发生了 after 两个动作都被处理了。
为了证明这个案例,我对项目做了如下修改:
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
在两个操作都已处理之前不会重新呈现。
所以,在这种情况下,唯一的额外工作是 getStateFromStores
被调用两次而不是一次,但我相信一点点额外的开销是值得的,以利用简化的心智模型只需从任何需要更新的商店发出更改事件。
请记住,通量的黄金法则是:改变存储数据的唯一方法是通过操作。在商店中公开的函数应该 永远不会 改变数据——它们应该是纯函数。因此,多次调用它们不会导致错误。