componentDidUpdate 中的 prevState 是 currentState?

Posted

技术标签:

【中文标题】componentDidUpdate 中的 prevState 是 currentState?【英文标题】:prevState in componentDidUpdate is the currentState? 【发布时间】:2018-06-11 23:28:48 【问题描述】:

我过去使用过componentDidUpdate(),它按预期工作。

这一次,我做到了

componentDidUpdate(prevProps, prevState) 
    if (prevState.object.someString !== this.state.object.someString) 
        console.log(true);
    

并且永远不会记录true。我将两个状态对象都记录到控制台,发现它们完全相同:当前状态。

这是一个错误吗?我在这里错过了什么?

谢谢。

编辑:我尝试对 componentWillUpdate(nextProps, nextState) 做同样的事情,而且它们是同一个对象。

编辑 2:我正在通过以下方式更改状态:

modifyObject = (field, value) => 
    const  object  = this.state;
    object[field] = value;
    this.setState( object );

【问题讨论】:

你能显示触发状态更新的其余代码吗?看起来状态实际上并未更新? 状态被对象的改变所修改,如下所示:modifyObject = (field, value) => const object = this.state; character[field] = value; this.setState( object ); character 是什么?它从何而来?你也没有改变你的 object 变量。从外观上看,您只是在像以前一样更新状态 componentDidUpdate 不仅在 state 改变时调用,而且在 parent 重新渲染或 props 改变时调用 你能展示一段代码来改变你的状态吗?我觉得很奇怪。 【参考方案1】:

感谢 Icepickle 的评论,解决了问题。

而不是做

modifyObject = (field, value) => 
    const  object  = this.state;
    object[field] = value;
    this.setState( object );

我做到了

modifyObject = (field, value) => 
    const  object  = this.state;
    this.setState( object:  ...object, [field]: value  );

再次感谢。

【讨论】:

【参考方案2】:

注意:

如果 shouldComponentUpdate() 返回 false,则不会调用 componentDidUpdate()。 参考:https://reactjs.org/docs/react-component.html#componentdidupdate

 shouldComponentUpdate(nextProps, nextState) 
    if (this.state.someString !== nextState.someString) 
      return true;
    
    return false;
  

componentDidUpdate(prevProps, prevState) 
    if (prevState.someString !== this.state.someString) 
        console.log(true);
    

在某些情况下,当您使用shouldComponentUpdate 时,最好使用类似 lodash isEqual 的方法来深入比较您的状态/道具:

shouldComponentUpdate(nextProps, nextState) 
        return !isEqual(this.state, nextState);
      

如果您有复杂的道具/状态,这将提高您的性能,因为不会发生浪费的渲染

【讨论】:

他的问题是他正在改变状态上的引用对象,lodash 会返回 false 与他的代码完全相同【参考方案3】:

在添加的代码中,您通过仅更改对象的属性来改变引用对象。这意味着最终nextPropspreviousProps 本质上指的是同一个引用。

因此,您的 componentDidUpdate 没有发现差异也就不足为奇了。

您应该做的是创建对象的新版本,并使用该版本来设置状态,例如:

this.setState( object:  ...object, [field]: value  )

或者如果你没有展开操作符,比如

this.setState(  object: Object.assign(, object,  [field]: value )  );

【讨论】:

以上是关于componentDidUpdate 中的 prevState 是 currentState?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用钩子清理 componentDidUpdate 中的异步函数

react native中componentdidmount和componentdidupdate之间的区别是什么

React app,componentDidUpdate - 跳转列表,无限循环

用componentDidUpdate()和React-APlayer库更新状态。

在 React.Js 中进行更新后的无限 componentDidUpdate() 渲染

mapStateToProps,但未调用componentDidUpdate