在React中,setState和forceUpdate有什么区别?

13
在一个不覆盖shouldComponentUpdate的组件中,forceUpdate和setState之间有什么区别吗?
更新:我已经知道文档上说了什么,也知道forceUpdate并不是推荐的方法。我只是想更深入地了解发生了什么。我想知道为什么?而且我已经知道setState会将传递的对象(状态“增量”——像SQL更新一样)与当前状态对象合并。
假设一个简单的用例:不需要撤消或时间旅行功能。不需要在shouldComponentUpdate内部进行指针比较。实际上,根本不需要使用shouldComponentUpdate。
在这种情况下,对我来说,改变状态并调用forceUpdate()是一种完全有效的使用React的方式。从黑盒子的角度来看,这两种技术似乎具有完全相同的效果:
技术 #1: this.state.x = 10; this.forceUpdate();
技术 #2: this.setState({x:10});
再次说明,我已经知道有些人喜欢永远不改变状态,并使用函数式编程风格。我只是想知道是否有任何技术原因要避免使用技术 #1。还是我漏了什么?

1
这两者之间没有相似之处,它们完全不同。setState 用于更新状态变量,然后 React 触发重新渲染,而通过 forceUpdate() 我们可以告诉 React 组件需要重新渲染。请查看此链接:https://dev59.com/IZPfa4cB1Zd3GeqPJOJJ - Mayank Shukla
使用技术1有一些不利之处:你可以在https://dev59.com/Xabja4cB1Zd3GeqPj665#47237601 上查看。 - Shubham Khatri
3个回答

30

setState()概述

setState() 函数通常用于使用一个或多个新状态属性来更新组件状态。这是改变状态和管理视图更新的典型方式。

官方文档中描述:

setState() 函数将更改排队到组件状态并告诉 React,需要使用更新后的状态重新渲染该组件及其子组件。这是您通过事件处理程序和服务器响应来更新用户界面的主要方法。


forceUpdate() 概述

forceUpdate()函数仅是一种强制重新渲染相关组件及其子组件的方式,并不会改变状态。

尽可能避免使用此函数,因为它偏离了 React 的思维方式,其中您的状态和道具是保持应用程序逻辑与视图同步的唯一责任。

官方文档中描述:

默认情况下,当组件的状态或道具发生更改时,组件将重新渲染。如果您的 render() 方法依赖于其他数据,则可以通过调用 forceUpdate() 告诉 React 组件需要重新渲染。

通常应尽量避免使用所有 forceUpdate() 用法,并仅在 render() 中从 this.propsthis.state 读取。


两者之间的区别

需要注意的是,forceUpdate()跳过检查 shouldComponentUpdate() 中的逻辑(如果有),而 setState() 不会跳过它。

这里有一个有趣的提示:以下两行代码将始终产生相同的结果:

this.setState(this.state);
this.forceUpdate();

......除非如上所述,shouldComponentUpdate() 可以返回false

除了上述情况外,这两者之间没有功能上的区别。


性能如何?基本上,如果子组件有新的状态,它会重新渲染吗? - TomSawyer
4
@TomSawyer,严格来说,forceUpdate() 可能会更快,因为它跳过了运行 shouldComponentUpdate() 的步骤。正如我上面解释的那样,它会触发所有子组件的重新渲染。但是,请务必使用 setState() - Chris

1
在《FullStack React》一书中,有一章节介绍了一个基本的计时器应用程序。在这一章节中,他们使用forceUpdate()来重新渲染UI,并给出以下解释:
“你可能会问:如果我们不对没有运行的计时器连续调用forceUpdate(),那么是否更高效呢? 确实,我们可以节省一些周期。但是,这并不值得增加代码复杂性。React将调用render()函数,在JavaScript中执行一些廉价操作。然后它会将此结果与先前调用render()的结果进行比较,并发现没有变化。它就会停止在那里,不会尝试任何DOM操作。” 摘自:Anthony Accomazzo、Ari Lerner、David Guttman、Nate Murray、Clay Allsopp和Tyler McGinnis的《Fullstack React》。
我理解这意味着,如果使用setState是可行的,那么您应该使用它以获得最大的性能;但是,如果所涉及的操作不昂贵,并且可以避免很多代码复杂性,那么使用forceUpdate()重新渲染UI也许是可以接受的。当然,这是我的解释,您可能需要阅读这本书以获取更多上下文信息,并可能会帮助您做出自己的决定。

在引用来源时,请使用引用块而不是代码块。 - Chris

-1

Flutter是一个基于React架构的框架。

我认为这篇Flutter博客文章实际上给出了最好的答案:

避免空状态回调

注意:Flutter的“空setState调用”与React的forceUpdate大致类似。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接