【问题标题】:Is it OK to call setState from within shouldComponentUpdate?可以从 shouldComponentUpdate 中调用 setState 吗?
【发布时间】:2016-01-22 06:32:52
【问题描述】:

为了响应状态变化,我想触发另一个状态变化。这本质上是个坏主意吗?

具体的场景是组件被建模为状态机,根据this.state.current_state的值呈现不同的信息。但是外部事件可以促使它经历状态转换,通过通量存储改变它的状态。这是一个人为的场景来传达这个想法:

我认为正确的生命周期方法是shouldComponentUpdate。大意是这样的:

shouldComponentUpdate: function(nextProps, nextState) {
    if (nextState.counter > 4 && this.state.current_state !== DISPLAY_MANY) {
        this.setState({ current_state: DISPLAY_MANY });
    }
    return true;
}

在某些子组件中,counter 可能会增加,因此我不想根据某些 counter 变量的值来推断它会显示什么,而是想显式地对状态进行编码。

真实的场景比这更复杂,但希望这个场景足够详细,可以理解这个想法。可以按照我的想法去做吗?

编辑:修复代码示例,通过添加额外的状态条件来避免触发无限循环

【问题讨论】:

标签: reactjs reactjs-flux flux


【解决方案1】:

shouldComponentUpdate 专门用于确定组件是否应该更新。执行以下操作:

if (nextState.counter == this.state.counter && nextProps.foo == this.Props.foo) {
  return false;
}

componentWillReceiveProps 用于响应 external (props) 的变化。正如文档中所指出的,没有等效的 componentWillReceiveState。您的组件(并且只有您的组件)触发它自己的状态更改,通常通过以下一个或多个事件:

  • getInitialState 中的初始渲染
  • 更新了componentWillReceiveProps中的道具
  • <input> 字段等中的用户交互,例如在组件中的自定义 onChangeInput() 函数中。
  • 不断变化:响应来自侦听器的存储更改,通常在调用 getStateFromStores() 的自定义函数中,其中状态已更新。

我猜在组件内部有一个函数来创建状态更改,然后在同一组件内部的另一个函数在状态更新之前进行干预是没有意义的。

在您的情况下,您可以将逻辑(以确定是否需要更新状态)移动到处理存储更新的 getStateFromStores() 函数。
或者,您可以简单地将其保持在状态,并更改您的渲染函数,以便在 counter > 4 时以不同的方式渲染。

【讨论】:

  • 更重要的是,setState 根本无法在shouldComponentUpdate 中工作。无论您返回true 还是false,它都不会应用于该渲染。您必须在下一个滴答声中使用计时器进行操作。然后shouldComponentUpdate 将立即重新运行。最终结果是复杂的代码。我做过这样的事情,最后得到了不可读的代码,并找到了其他方法来做我需要的事情(通常是关于动画)。
  • 我强烈建议掌握低级ReactTransitionGroup。通过它,您可以清晰而惯用地完成许多动画内容。基本上,它的willLeave 方法让一切再次变得简单。通常,您尝试做的是将组件保留在 DOM 中,同时对其进行动画处理——这就是它的亮点。更重要的是,它允许您通过一个简单的布尔道具之间的比较界面来确定是否隐藏/显示元素。然后,当您被告知进入/出现或离开时,您的动画会被单独且干净地处理。
【解决方案2】:

没有。请改用componentWillReceiveProps。它具有与shouldComponentUpdate 相同的签名,您可以安全地在那里调用this.setState

【讨论】:

  • componentWillReceiveProps 只会得到新的道具,而不是新的状态;在此处查看生命周期文档:facebook.github.io/react/docs/component-specs.html
  • 我的错。正如文档所说,没有这样的东西叫做componentWillReceiveState。所以我的建议是。将逻辑提取到另一个组件并在其componentWillReceiveProps 中处理它。这更有意义。
  • 那行得通。所以明确地说,我建议的是反模式?具体原因是什么,有没有人如此明确地提到过?
  • 我认为这只是文档不希望(或鼓励)您这样做(尽管这可能工作得很好)。更具体地说,shouldComponentUpdate 应该是基于this.props/statenextProps/State 的纯函数。
  • componentWillReceiveProps 无论如何都被标记为弃用
猜你喜欢
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 2020-08-29
  • 2020-04-11
  • 2011-04-03
  • 2014-06-21
  • 1970-01-01
  • 2018-09-05
相关资源
最近更新 更多