【问题标题】:React: What is the performance penalty of calling setState after mutating the state directly in the component?React:在组件中直接改变状态后调用 setState 的性能损失是什么?
【发布时间】:2023-03-17 08:54:01
【问题描述】:

由于每个 setState* 都会调用组件的 render 方法,我想知道如果我直接修改状态属性,使用空对象调用 setState({}) 并让组件完全呈现自身,会造成性能损失。这对状态管理有一个有趣的副作用:在这种情况下,状态用作可变对象而不是不可变对象。由于组件将在 setState 调用后使用新的状态值重新渲染,因此它将在视图中反映新的值。当然,React 团队不建议改变状态,因为他们建议将状态视为只读对象,但在某些情况下,处理可变对象变得更容易进行状态管理。

我知道这不是最佳做法,可能会立即引起一些人的注意,但我不能停下来询问它在典型应用程序中可能导致的性能影响或任何其他潜在问题。

请看以下示例进行简单演示:https://codesandbox.io/s/k5zy9zw8kv

所以,请告诉我你的想法。

谢谢。

* 除非 shouldComponentUpdate 已在组件内实现并根据当前状态和 nextState 值返回 false。

PS:我个人的看法,对于状态管理来说,中大型应用还是用 MobX 比较好。我的问题主要是针对相对较小的应用程序。我认为 react 和 redux 都使状态管理变得不必要地复杂。作为具有 OO 背景的开发人员,我希望看到更简单、更优雅的解决方案。

【问题讨论】:

  • 您关于变异状态带来更容易的评论是错误的。在我看来,这并不容易做到,但它需要更少的思考。什么是不可变或只读...这意味着您的数据和状态与您的组件分离...如果您认为这更难尝试创建多个组件需要相同数据并让这些组件能够编辑的关系 ui相同的数据...史诗般的噩梦
  • 性能将是您对这种方法最不关心的问题。这不仅仅是一些“最佳实践”,不可变状态是 React 库的核心思想。试图解决它就像把一匹马放在你的车前。

标签: reactjs state state-management


【解决方案1】:

这是个糟糕的主意。

1。官方不支持

直接状态突变是未记录、不受支持和未经测试的,因此 React 团队可以跨版本更改行为(无需测试/记录)。

2。破坏生命周期方法

您破坏了几个生命周期方法,例如componentDidUpdate,因为prevState 将不是突变之前的状态,因此您放弃了使用这些方法的选项,以防将来需要它们。

3。而是保持状态浅

处理可变对象变得更容易进行状态管理

当您有深度嵌套的状态时,您可能会有这种感觉,因此修改嵌套属性(例如product.quality)需要先克隆整个对象(例如products)。

建议让您的状态尽可能浅,既可以简化状态更改,也可以更轻松地优化性能。例如。如果您的状态很浅,将其声明为 PureComponent 将避免它在父组件重新渲染而子组件没有更改时调用 render

在您的示例中,您可以将状态移动到 Product

class Product {
  state = { quantity: 0 };
  ...
  this.setState(prevState => ({ quantity: prevState.quantity + 1 }));
} 

【讨论】:

    猜你喜欢
    • 2019-07-10
    • 2017-11-18
    • 1970-01-01
    • 2017-09-27
    • 2017-11-19
    • 2015-08-27
    相关资源
    最近更新 更多