【问题标题】:React / Flux, setting multiple statesReact / Flux,设置多种状态
【发布时间】:2015-11-19 21:22:25
【问题描述】:

我是新手,我正在为我的数据模型使用状态。

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

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

我使用的是标准通量模式。

以下是相关代码:

菜单.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 '有些东西已经改变了'?

哪种是正确的 React / Flux 模式?在一个回调中设置所有状态?还是分别设置所有状态?

【问题讨论】:

  • 为什么切换菜单时需要设置头像?

标签: reactjs reactjs-flux


【解决方案1】:

我在使用 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 时不会调用此方法。 当您确定转换到新的 props 和 state 不需要组件更新时,可以利用这个机会返回 false。

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

另外,请记住,React 非常快。除非您有超过 100 个组件在监听更改,否则有时最好浪费一些重新渲染周期,而不是编写复杂的 shouldComponentUpdate

代码可读性与性能

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

这确实是一种权衡。如果您有大约 100 个组件正在侦听同一个商店,其中一些只对一个事件感兴趣,而另一些对另一个事件感兴趣,那么就会出现不同的事件(无论如何您都将继续发送整个快照)。否则,我建议让您的代码保持简单:只需发布一个事件。

助焊剂有不同的口味

现在有一些库实现了来自 Flux 的想法。我建议你看看Reflux,尤其是Redux

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-13
    • 2017-05-30
    • 2017-01-25
    • 2015-06-23
    • 1970-01-01
    • 2016-08-08
    • 2015-08-06
    • 1970-01-01
    相关资源
    最近更新 更多