ReactJS render() 方法在复杂的 RefluxJS 应用程序中被调用得比必要的更频繁
ReactJS render() method called more often than necessary in complex RefluxJS application
我有一个 RefluxJS 应用程序,它有几个商店和一个非常深的组件层次结构。我试图让组件非常独立,每个组件都连接到它需要渲染的商店;商店本身有时会调用其他商店收听的操作。
我发现我收到了很多对组件的 render() 方法的虚假调用,因为两个商店可能会监听相同的操作,而层次结构中的不同组件可能会监听那些不同的商店。这会影响用户体验,因为有时会有一点延迟。
这是一些代码:
var Actions = Reflux.createActions(['changeUser']);
Actions.changeUser.preEmit = () => console.log('Action emit: changeUser');
var UserStore = Reflux.createStore({
listenables: [Actions],
onChangeUser(user) {
this.trigger(user);
}
});
var MessageStore = Reflux.createStore({
listenables: [Actions],
onChangeUser(user) {
setTimeout(() => {
// pretend we had to go to an API or something to get this
var message = "Welcome to the app!";
this.trigger(message);
}, 500);
},
});
var App = React.createClass({
mixins: [Reflux.connect(UserStore, 'user')],
render() {
console.log('Component render: App');
if (!this.state.user) {
return (
<button onClick={() => Actions.changeUser('Some User')}>
Click to make stuff happen
</button>
);
}
return (
<div>
<div>Hello, {this.state.user}.</div>
<Message / >
</div>
);
}
});
var Message = React.createClass({
mixins: [Reflux.connect(MessageStore, 'message')],
render() {
console.log('Component render: Message');
return <div>Your message: {this.state.message}</div>;
}
});
ReactDOM.render( <App/> , document.getElementById('app'));
Fiddle: https://jsfiddle.net/9xwnxos6/
这过于简单化了(在这个例子中我可能只是添加了某种加载指示器),但说明了一个基本问题,即您可以看到 UI 在您进行中间状态转换时正在做事
如何改进我的 React/Reflux 设计以避免一次交互触发多个渲染?
看来我的问题是因为违反了一些好的 React/Flux 做法:
- 不要从商店中触发操作
- 仅连接到高级组件中的商店
我正在重构以从低级组件中获取商店连接。我对此并不疯狂,因为这意味着我必须通过这些深层组件层次结构传递各种道具,以将它们送到需要的地方。但这似乎是构建 Reflux 应用程序的 "right" 方法。
如果在接下来的几天内没有其他人发布答案,我会接受这个。
我有一个 RefluxJS 应用程序,它有几个商店和一个非常深的组件层次结构。我试图让组件非常独立,每个组件都连接到它需要渲染的商店;商店本身有时会调用其他商店收听的操作。
我发现我收到了很多对组件的 render() 方法的虚假调用,因为两个商店可能会监听相同的操作,而层次结构中的不同组件可能会监听那些不同的商店。这会影响用户体验,因为有时会有一点延迟。
这是一些代码:
var Actions = Reflux.createActions(['changeUser']);
Actions.changeUser.preEmit = () => console.log('Action emit: changeUser');
var UserStore = Reflux.createStore({
listenables: [Actions],
onChangeUser(user) {
this.trigger(user);
}
});
var MessageStore = Reflux.createStore({
listenables: [Actions],
onChangeUser(user) {
setTimeout(() => {
// pretend we had to go to an API or something to get this
var message = "Welcome to the app!";
this.trigger(message);
}, 500);
},
});
var App = React.createClass({
mixins: [Reflux.connect(UserStore, 'user')],
render() {
console.log('Component render: App');
if (!this.state.user) {
return (
<button onClick={() => Actions.changeUser('Some User')}>
Click to make stuff happen
</button>
);
}
return (
<div>
<div>Hello, {this.state.user}.</div>
<Message / >
</div>
);
}
});
var Message = React.createClass({
mixins: [Reflux.connect(MessageStore, 'message')],
render() {
console.log('Component render: Message');
return <div>Your message: {this.state.message}</div>;
}
});
ReactDOM.render( <App/> , document.getElementById('app'));
Fiddle: https://jsfiddle.net/9xwnxos6/
这过于简单化了(在这个例子中我可能只是添加了某种加载指示器),但说明了一个基本问题,即您可以看到 UI 在您进行中间状态转换时正在做事
如何改进我的 React/Reflux 设计以避免一次交互触发多个渲染?
看来我的问题是因为违反了一些好的 React/Flux 做法:
- 不要从商店中触发操作
- 仅连接到高级组件中的商店
我正在重构以从低级组件中获取商店连接。我对此并不疯狂,因为这意味着我必须通过这些深层组件层次结构传递各种道具,以将它们送到需要的地方。但这似乎是构建 Reflux 应用程序的 "right" 方法。
如果在接下来的几天内没有其他人发布答案,我会接受这个。