React.js中setState的快速介绍

by Rajesh Pillai

由Rajesh Pillai

React.js中setState的快速介绍 (A quick intro to setState in React.js)

如何有效使用setState以及应避免的陷阱 (How to use setState effectively and what pitfalls to avoid)

TL;DR — In case you are a visual learner, head over to the video I made: ReactJS — How setState works

TL; DR —如果您是视觉学习者,请转到我制作的视频: ReactJS — setState的工作方式

Or watch it here:

或在这里观看:

setState简介 (An introduction to setState)

The first thing to be aware of is the fact that the setState function in React works in an asynchronous fashion. That might trip some developers up, as the state values are not immediately available after the update.

首先要知道的是,React中的setState函数以异步方式工作。 这可能会使某些开发人员不高兴,因为更新后状态值无法立即使用。

There are two variations of using setState: the object-based approach and the functional approach.

使用setState有两种变体:基于对象的方法和功能的方法。

Let’s see both in action. We’ll get to understand the issue with object based setState in the process.

让我们看看两者都在起作用。 我们将在过程中了解基于对象的setState的问题。

Let’s create a simple application.

让我们创建一个简单的应用程序。

class App extends React.Component {   constructor() {     super();     this.state = {       value: 0,       message: 'default click state'     }   }     onClick = () => {     this.setState({       value: this.state.value + 1     });          this.setState({       message: `click-state ${this.state.value}`     });   }         render(){     return(        <div>         <div>render->state={this.state.value} -              {this.state.message}         </div>         <button onClick={this.onClick}>Click-setState</button>               </div>     );   }}

Now we’ll mount this application to our root DOM node.

现在,我们将该应用程序安装到我们的根DOM节点。

ReactDOM.render(  <App />,   document.getElementById("root"));

The above code, when executed, renders the value and message from the state object and also renders a button.

上面的代码在执行时会呈现状态对象中的值和消息,还会呈现一个按钮。

If you take a look at the click handler, we have two consecutive setState functions that access the this.state value.

如果您看一下单击处理程序,我们有两个连续的setState函数访问this.state值。

The behavior we are expecting is that when the button is clicked, the correct state value should be rendered in the below div (extracted for reference):

我们期望的行为是,当单击按钮时,正确的状态值应在下面的div中呈现(提取以供参考):

<div>render->state={this.state.value} -      {this.state.message}</div>

The this.state.message contains values from this.state.value

this.state.message包含来自this.state.value

We are expecting that both state values should be the same when the button is clicked.

我们期望单击按钮时两个状态值应该相同。

Let’s see the output of this.

让我们看看它的输出。

The initial output is shown below, as the value is 0 to start with.

初始输出如下所示,从0开始。

After the first click, we expect the below output:

首次点击后,我们期待以下输出:

render->state=1 -click-state 1

but we are getting this instead:

但是我们得到的却是:

On the second click, the output still mismatches as shown below.

第二次单击时,输出仍然不匹配,如下所示。

By now you might be snoozing or scratching your head :)

现在,您可能正在打oo或挠头:)

onClick()函数 (The onClick() function)

So let’s take a look at the onClick() function to understand the issue.

因此,让我们看一下onClick()函数以了解问题。

Since the setState call is asynchronous before the first setState execution may be completed, the reference to the second setState may point to the previous value and not the first current updated one.

由于setState调用在完成第一个setState执行之前是异步的,因此对第二setState的引用可能指向先前的值,而不是第一个当前更新的值。

We’ll fix this by using the functional aspect of setState.

我们将使用setState的功能方面解决此问题。

To demonstrate the fix, let’s create one more button:

为了演示此修复程序,让我们再创建一个按钮:

<button onClick={this.onClickfn}>Click-setState fn</button>

And add a new click handler onClickfn() as shown below

并添加一个新的点击处理程序onClickfn(),如下所示

The above method uses the functional parameter in setState.

上面的方法使用setState中的功能参数。

This can be an arrow function as shown above or the normal ES5 function.

这可以是上面显示的箭头功能,也可以是正常的ES5功能。

This function takes two parameters as arguments: the first is the prevState, and the second is the props (in case you need props as well, which is passed from the parent component). Here we are only looking into the prevState.

该函数使用两个参数作为参数:第一个是prevState,第二个是props(如果您还需要props,它是从父组件传递来的)。 在这里,我们仅研究prevState。

The prevState above relates to the setState function as it is the last updated state. This will always point to the correct value.

上面的prevState与setState函数有关,因为它是最后更新的状态。 这将始终指向正确的值。

Let’s see the output after couple of clicks. You will find that the values are always in sync when you click the second button.

让我们看看几次点击后的输出。 单击第二个按钮时,您将发现这些值始终保持同步。

In the above example, you can see that using the functional setState parameter correctly batches the previous state, and you get predictable state values.

在上面的示例中,您可以看到使用功能性setState参数正确地批处理了先前的状态,并且获得了可预测的状态值。

One more caveat we need to be aware of: setState() takes one more callback function, which is executed once the state values are successfully updated.

我们需要注意的另一点警告:setState()需要再执行一个回调函数,该回调函数将在状态值成功更新后执行。

This is very handy in a situation where you have to do some operation once setState successfully updates.

在setState成功更新后必须执行一些操作的情况下,这非常方便。

Let’s see a final example.

让我们来看一个最后的例子。

Assume we want to log the state value after the update, and we write the code as below. I will use the onClickfn() handler for this.

假设我们要在更新后记录状态值,并编写如下代码。 我将为此使用onClickfn()处理程序。

But lets see the console.log and verify whether the value is correct or not. After three clicks, you get this status:

但是让我们查看console.log并验证该值是否正确。 单击三下后,您将获得以下状态:

You will observe that the logged value is not the last updated value. Let’s fix this and see the output.

您将观察到记录的值不是最后更新的值。 让我们修复此问题并查看输出。

In the above example, we are using the setState() second callback parameter. This callback will be executed once the setState() has completed its operation.

在上面的示例中,我们使用setState()第二个回调参数。 一旦setState()完成其操作,便将执行此回调。

Let’s see the final output with the above modified code.

让我们看一下上面修改后的代码的最终输出。

结语 (Wrapping up)

I hope this small article clears up some misconceptions about setState.

我希望这篇小文章能消除对setState的一些误解。

The complete source code is available at jsbin.

完整的源代码可在jsbin上获得

Happy coding!

编码愉快!

Learn with me @Learner + Fullstack Coach (@rajeshpillai): https://twitter.com/rajeshpillai

与我一起学习@Learner + Fullstack Coach(@rajeshpillai): https ://twitter.com/rajeshpillai

Promotion: Special $10 coupon for medium readers for my upcoming live ReactJS-Beyond the basics course on udemy in case you wish to support our open source curriculum Mastering frontend engineering in 12 to 20 weeks

促销:我即将举行的现场ReactJS现场读者特别优惠券$ 10- 超越了udemy的基础知识课程,如果您希望在12至20周内支持我们的开源课程, 掌握前端工程

翻译自: https://www.freecodecamp.org/news/understanding-setstate-in-react-ea8982168b49/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值