setState的几种方法而不是单一方法

时间:2018-01-16 12:16:47

标签: reactjs

我正在开发一个没有Redux或任何其他州经理的React应用程序。

假设我想在点击按钮时做三件事:

  1. 启用其他按钮
  2. 删除标签
  3. 显示确认烤面包机
  4. 这3件事由3个状态变量控制。因此,我可以这样做:

    myHandler = () => {
        this.setState({
            canSave: true,                      // Enable the button
            isLabelVisible: false,              // Hide label
            isConfirmationMessageVisible: true, // Show confirmation message
        });
    }
    

    但是,我可以通过使用一些私有类函数来删除这些注释,如下所示:

    myHandler = () => {
        this.toggleSaveButton(true);
        this.toggleLabel(false);
        this.toggleConfirmationMessage(true);
    }
    
    toggleSaveButton= (enabled) => {
        this.setState({
            canSave: enabled,
        });
    }
    
    toggleLabel= (visible) => {
        this.setState({
            isLabelVisible: visible,
        });
    }
    
    toggleConfirmationMessage= (visible) => {
        this.setState({
            isConfirmationMessageVisible: visible,
        });
    }
    

    除了删除那些容易与代码不同步的注释外,这还允许我在代码的其他地方重用私有方法。

    由于这是在合成事件中处理的,因此我已阅读here它将被批处理,因此我预计不会有性能损失。

    我的问题是:这是一个好习惯吗?你用过这种方法吗?你能指出一些我现在无法预见的潜在缺点吗?

1 个答案:

答案 0 :(得分:1)

这很好。正如您所提到的,React批处理从事件处理程序触发的状态的所有更新。这意味着您可以像在这里一样安全地使用多个setState()

  

在当前版本中,如果您在React事件处理程序中,它们将被批处理。 React批处理在React事件处理程序期间完成的所有setStates,并在退出其自己的浏览器事件处理程序之前应用它们。

您唯一需要注意的是,如果您要从两个setState()调用中更改两次相同的状态。例如:

a() {
  this.setState({foo: foo+1});
}
b() {
  this.setState({foo: foo+1});
}

从同一事件中调用a()然后b(),会将foo增加1,而不是2。

改为使用:

a() {
  this.setState(prevState => ({foo: foo+1}));
}
b() {
  this.setState(prevState => ({foo: foo+1}));
}

这会将foo正确地增加2。

对于从事件处理程序调用多个setState()的潜在未来读者,我应该注意以下内容:

  

对于当前版本,事件处理程序之外的几个setStates(例如在网络响应中)将不会被批处理。所以在这种情况下你会得到两次重新渲染。

替代解决方案

无论您是否从事件处理程序调用{​​{1}},您可以做的是构建一个对象,然后将其设置为新状态。这里的潜在好处是你只设置一次状态,因此不依赖于批处理或从(事件处理程序与否)触发函数的位置。

类似于:

setState()