我正在开发一个没有Redux或任何其他州经理的React应用程序。
假设我想在点击按钮时做三件事:
这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它将被批处理,因此我预计不会有性能损失。
我的问题是:这是一个好习惯吗?你用过这种方法吗?你能指出一些我现在无法预见的潜在缺点吗?
答案 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()