React / Flux,设置多个状态
React / Flux, setting multiple states
我是 React 新手,我正在为我的数据模型使用状态。
我有一个通过状态显示用户个人资料图片的菜单。这是状态,因为用户可以更改他的个人资料图片。
我希望菜单从左侧滑入,最初是隐藏的。因此,我想将菜单的 open/close 状态也添加为状态。
我正在使用标准的 Flux 模式。
相关代码如下:
Menu.js
_onChange:function(){
this.setState({
opened: MenuStore.getMenuState(),
profilePicUrl: MenuStore.getUserPic()
})
},
componentDidMount:function(){
MenuStore.addChangeListener(this._onChange)
}
MenuStore.js
MenuStore = assign({},EventEmitter.prototype,{
emitChange: function() {
this.emit(CHANGE_EVENT);
},
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
...(rest of class not shown)
})
MenuStore.dispatchToken = Dispatcher.register(function(action) {
switch(action.type) {
case ActionTypes.RECEIVE_USER_DATA:
_userData = action.details;
MenuStore.emitChange();
break;
case ActionTypes.TOGGLE_MENU:
_opened = !_opened;
MenuStore.emitChange();
break;
default:
// do nothing
}
});
Nav.js
toggleMenu:function(){
Actions.toggleMenu(); //in my actions.js it dispatches TOGGLE_MENU
}
render:function(){
return <div onClick={this.toggleMenu}>My Nav button</div>
}
我想我觉得奇怪的是,我正在设置用户个人资料图片的状态,但没有更改。这是正确的做事方式吗?或者我应该发出单独的更改事件并因此使用单独的回调,以便单独设置状态?
一个相关的问题是 React 是否会关心我是否设置了未更改的状态。即差异算法是否会忽略用户的个人资料图片,因为它没有改变,因此对 React 没有影响?或者我已经将状态设置为 React 的事实,隐含地告诉 React 'something has changed'?
哪个是正确的 React / Flux 模式?在一个回调中设置所有状态?还是单独设置所有状态?
我在使用 React 和 Flux 时学到了一些东西,我希望它们可以改进您的方法:
使用发出的事件传送整个状态
在您的示例中,您正在发出一个事件,然后该组件正在请求数据:
_onChange:function(){
this.setState({
opened: MenuStore.getMenuState(),
profilePicUrl: MenuStore.getUserPic()
})
}
我建议你换一种不同的模式,无论事件如何,每次它发出一个事件时,store 都会发送整个状态:
case ActionTypes.TOGGLE_MENU:
_opened = !_opened;
MenuStore.emitChange({opened: _opened, /* [...] */});
break;
然后在你的组件中:
_onChange:function(snapshot){
this.setState({
opened: snapshot.opened,
profilePicUrl: snapshot.profilePicUrl
})
}
通过这种方式,您的商店 可以扩展 ,无论您想在商店中保留多少数据。
考虑使用 Immutable.js 或已发布的不变性助手
A related question is whether React will care if I set the state of something that hasn't changed.
React 将在虚拟 DOM 中触发虚拟重新渲染。然后,它将执行 diff 算法。由于没有任何改变,因此不会重新渲染任何内容。
您可以通过覆盖 shouldComponentUpdate
:
来避免这种情况
Invoked before rendering when new props or state are being received. This method is not called for the initial render or when forceUpdate is used.
Use this as an opportunity to return false when you're certain that the transition to the new props and state will not require a component update.
我强烈建议您开始使用 immutability helpers, or Immutable.js。通过这种方式,管理整个重新渲染过程变得更加容易,因为了解什么时候真正发生了变化变得微不足道。
此外,请记住 React 非常快。除非你有超过 100 个组件监听变化,有时最好是有一些浪费的重新渲染周期,而不是写一个令人费解的 shouldComponentUpdate
.
代码可读性与性能
I guess what I find weird, is that I am setting the state of the User's profile picture without it having changed.
这真是一个权衡。如果你有大约 100 个组件在监听同一个存储,其中一些只对一个事件感兴趣,其他的对另一个事件感兴趣,那么就会有不同的事件(无论如何你都会继续发送整个快照)。否则,我建议您保持代码简单:只发布一个事件。
助焊剂有不同的口味
我是 React 新手,我正在为我的数据模型使用状态。
我有一个通过状态显示用户个人资料图片的菜单。这是状态,因为用户可以更改他的个人资料图片。
我希望菜单从左侧滑入,最初是隐藏的。因此,我想将菜单的 open/close 状态也添加为状态。
我正在使用标准的 Flux 模式。
相关代码如下:
Menu.js
_onChange:function(){
this.setState({
opened: MenuStore.getMenuState(),
profilePicUrl: MenuStore.getUserPic()
})
},
componentDidMount:function(){
MenuStore.addChangeListener(this._onChange)
}
MenuStore.js
MenuStore = assign({},EventEmitter.prototype,{
emitChange: function() {
this.emit(CHANGE_EVENT);
},
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
...(rest of class not shown)
})
MenuStore.dispatchToken = Dispatcher.register(function(action) {
switch(action.type) {
case ActionTypes.RECEIVE_USER_DATA:
_userData = action.details;
MenuStore.emitChange();
break;
case ActionTypes.TOGGLE_MENU:
_opened = !_opened;
MenuStore.emitChange();
break;
default:
// do nothing
}
});
Nav.js
toggleMenu:function(){
Actions.toggleMenu(); //in my actions.js it dispatches TOGGLE_MENU
}
render:function(){
return <div onClick={this.toggleMenu}>My Nav button</div>
}
我想我觉得奇怪的是,我正在设置用户个人资料图片的状态,但没有更改。这是正确的做事方式吗?或者我应该发出单独的更改事件并因此使用单独的回调,以便单独设置状态?
一个相关的问题是 React 是否会关心我是否设置了未更改的状态。即差异算法是否会忽略用户的个人资料图片,因为它没有改变,因此对 React 没有影响?或者我已经将状态设置为 React 的事实,隐含地告诉 React 'something has changed'?
哪个是正确的 React / Flux 模式?在一个回调中设置所有状态?还是单独设置所有状态?
我在使用 React 和 Flux 时学到了一些东西,我希望它们可以改进您的方法:
使用发出的事件传送整个状态
在您的示例中,您正在发出一个事件,然后该组件正在请求数据:
_onChange:function(){
this.setState({
opened: MenuStore.getMenuState(),
profilePicUrl: MenuStore.getUserPic()
})
}
我建议你换一种不同的模式,无论事件如何,每次它发出一个事件时,store 都会发送整个状态:
case ActionTypes.TOGGLE_MENU:
_opened = !_opened;
MenuStore.emitChange({opened: _opened, /* [...] */});
break;
然后在你的组件中:
_onChange:function(snapshot){
this.setState({
opened: snapshot.opened,
profilePicUrl: snapshot.profilePicUrl
})
}
通过这种方式,您的商店 可以扩展 ,无论您想在商店中保留多少数据。
考虑使用 Immutable.js 或已发布的不变性助手
A related question is whether React will care if I set the state of something that hasn't changed.
React 将在虚拟 DOM 中触发虚拟重新渲染。然后,它将执行 diff 算法。由于没有任何改变,因此不会重新渲染任何内容。
您可以通过覆盖 shouldComponentUpdate
:
Invoked before rendering when new props or state are being received. This method is not called for the initial render or when forceUpdate is used. Use this as an opportunity to return false when you're certain that the transition to the new props and state will not require a component update.
我强烈建议您开始使用 immutability helpers, or Immutable.js。通过这种方式,管理整个重新渲染过程变得更加容易,因为了解什么时候真正发生了变化变得微不足道。
此外,请记住 React 非常快。除非你有超过 100 个组件监听变化,有时最好是有一些浪费的重新渲染周期,而不是写一个令人费解的 shouldComponentUpdate
.
代码可读性与性能
I guess what I find weird, is that I am setting the state of the User's profile picture without it having changed.
这真是一个权衡。如果你有大约 100 个组件在监听同一个存储,其中一些只对一个事件感兴趣,其他的对另一个事件感兴趣,那么就会有不同的事件(无论如何你都会继续发送整个快照)。否则,我建议您保持代码简单:只发布一个事件。