React / Flux,设置多个状态

时间:2015-08-26 01:05:34

标签: reactjs reactjs-flux

我有新的反应,我正在为我的数据模型使用状态。

我有一个菜单,通过状态显示用户的个人资料图片。它的状态是因为用户可以更改他的个人资料图片。

我希望菜单从左侧滑入,最初隐藏。因此,我想将菜单的打开/关闭状态添加为状态。

我使用标准的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 / Flux模式正确?在一个回调中设置所有状态?或者分别设置所有状态?

1 个答案:

答案 0 :(得分:6)

我学习了一些与React和Flux合作的东西,希望能改进你的方法:

使用发出的事件

运送整个州

在您的示例中,您正在发出一个事件,然后该组件正在请求数据:

_onChange:function(){
    this.setState({
        opened: MenuStore.getMenuState(),
        profilePicUrl: MenuStore.getUserPic()
    })
}

我建议你转移到另一种模式,商店每次发出一个事件时都会发送整个状态,无论事件如何:

case ActionTypes.TOGGLE_MENU:
    _opened = !_opened;
    MenuStore.emitChange({opened: _opened, /* [...] */});
    break;

然后在你的组件中:

_onChange:function(snapshot){
    this.setState({
        opened: snapshot.opened,
        profilePicUrl: snapshot.profilePicUrl
    })
}

通过这种方式,您的商店可以扩展,无论您想要在商店中保留多少数据。

考虑使用Immutable.js或发送不变性助手

  

一个相关的问题是,如果我设置了一些没有改变的状态,React是否会关心。

React将在虚拟DOM中触发虚拟重新渲染。然后,它将执行diff算法。没有任何改变,任何东西都不会被重新渲染。 您可以通过覆盖shouldComponentUpdate

来避免这种情况
  

在收到新道具或州时,在渲染前调用。初始渲染或使用forceUpdate时不调用此方法。   当您确定转换到新的道具和状态不需要更新组件时,请将此作为返回false的机会。

我强烈建议您开始使用immutability helpersImmutable.js。通过这种方式,管理整个重新渲染过程变得更加容易,因为当事情确实发生变化时,理解变得微不足道。

另外,请记住React非常快。除非你有&gt; 100个组件正在侦听更改,有时最好有一些浪费的重新渲染周期,而不是编写一个错综复杂的shouldComponentUpdate

代码可读性与性能

  

我想我觉得奇怪的是,我正在设置用户个人资料图片的状态,而不会更改。

这真的是一种折衷。如果你有大约100个组件正在监听同一个商店,其中一些只对一个事件感兴趣,而另一个对另一个事件感兴趣,那么就会出现不同的事件(你会继续发送整个快照)。否则,我建议保持你的代码简单:只发布一个事件。

Flux有不同的风味

现在有一些库实现了从Flux中获取的想法。我建议您查看Reflux,尤其是Redux