何时使用函数式 setState [英] When to use functional setState

查看:32
本文介绍了何时使用函数式 setState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去几天我一直在学习 React,查看了一些关于编写不同元素的不同方式的教程和解释.然而,有一个我最好奇的 - setState 函数来更新/覆盖组件的 state 属性.

例如,假设我有一个具有以下内容的类:

class Photos 扩展 React.Component {构造函数(){极好的()状态 = {图片: []}}componentDidMount() {//这是 fetch 和 setState 将发生的地方(见下文)}使成为() {返回 {<div className="容器">{this.state.pictures}

}}}

这个例子让我从 API 中获取图像.

鉴于我已经为这个函数执行了获取、映射和返回 - 然后我将使用 API 调用中获得的结果更新 pictures: [] 状态数组.

我的问题源于我所看到的关于如何更新/覆盖图片状态属性的不同方法.

我看到它以两种不同的方式编写:

1) 这似乎是一个非常简单易读的方法

this.setState({pictures: pics})

2) 这更复杂,但我认为它是一种更安全的方法

this.setState(prevState => ({图片:prevState.pictures.concat(图片)}))

有人可以解释一下使用两者的优点吗?以后想和代码保持一致,处理props和states等,所以当然首选最通用的方法.

解决方案

首先,在您的情况下,这两种语法完全不同,您可能要寻找的是

之间的区别

this.setState({pictures: this.state.picture.concat(pics)})

this.setState(prevState => ({图片:prevState.pictures.concat(图片)}))

要理解为什么第二种方法是首选方法,您需要了解 React 在内部对 setState() 做了什么.

React 将首先将您传递给 setState() 的对象合并到当前状态中.然后它会开始和解的事情.由于调用 setState() 可能不会立即更新您的状态.

React 可以将多个 setState() 调用批处理为单个更新以获得更好的性能.

考虑一个简单的例子,为了理解这一点,在你的函数中你可能会多次调用 setState() ,比如:

myFunction = () =>{...this.setState({图片: this.state.picture.concat(pics1)})this.setState({图片: this.state.picture.concat(pics1)})this.setState({图片: this.state.picture.concat(pics1)})...}

这在一个简单的应用程序中不是一个有效的用例,但随着应用程序变得复杂,多个 setState() 调用可能会从多个地方发生,做同样的事情.

所以现在为了执行有效的更新,React 通过提取传递给每个 setState() 调用的所有对象来进行批处理,将它们合并在一起形成一个对象,然后使用该对象做setState().根据 setState() 文档:

<块引用>

这种形式的setState()也是异步的,同一个周期内的多次调用可能会被批处理在一起.例如,如果您尝试在同一周期内多次增加商品数量,则结果相当于:

Object.assign(以前的状态,{数量:状态.数量+ 1},{数量:状态.数量+ 1},...)

后续调用将覆盖同一周期中先前调用的值,因此数量只会增加一次.如果下一个状态取决于当前状态,我们建议使用更新程序函数形式,而不是:

this.setState((state) => {返回{数量:状态.数量+ 1};});

更多详细信息,请参见:

setState() - 其他 API - React.Component– 反应.

因此,如果任何对象包含相同的键,则存储具有相同键的最后一个对象的键的值.因此,更新只使用最后一个值发生一次.

Demo Codesandbox

I have been learning React over the past few days, looking at a few tutorials and explanations regarding the different ways in which you can write different elements. However there is one I have been most curious about - the setState function to update/override the state properties of a component.

For example, imagine I have a class with the following:

class Photos extends React.Component {
    constructor() {
        super()
        state = {
            pictures: []
        }
    }

   componentDidMount() {
      // This is where the fetch and setState will occur (see below)
   }

    render() {
       return {
          <div className="container">
             {this.state.pictures}
          </div>
       }
    }
}

This example sees me fetch images from an API.

Given that I have performed my fetch, map and return for this function - I will then update the pictures: [] state array with the results gained in the API call.

My question stems from the differing methods I have seen regarding how to update/override the pictures state property.

I have seen it written in 2 varying ways:

1) This seems to be a very simple and easy to read method

this.setState({pictures: pics})

2) This is more complex but I have see it described as a more safe method

this.setState(prevState => ({
   pictures: prevState.pictures.concat(pics)
}))

Could somebody please explain the merits of using either? I want to be consistent with code in the future, dealing with props and states etc, so the most versatile method would of course be preferred.

解决方案

First things first, in your case the two syntaxes are entirely different, what you might be looking for is the difference between

this.setState({pictures: this.state.picture.concat(pics)})

and

this.setState(prevState => ({
   pictures: prevState.pictures.concat(pics)
}))

To understand why the second method is a preferred one,you need to understand what React does with setState() internally.

React will first merge the object you passed to setState() into the current state. Then it will start that reconciliation thing. Because of the calling setState() might not immediately update your state.

React may batch multiple setState() calls into a single update for better performance.

Consider the simple case, to understand this, in your function you might call setState() more than once like:

myFunction = () => {

   ...
   this.setState({pictures: this.state.picture.concat(pics1)})
   this.setState({pictures: this.state.picture.concat(pics1)})
   this.setState({pictures: this.state.picture.concat(pics1)})

   ...
}

which isn't a valid use case in a simple app but as the app gets complex, multiple setState() calls may be happening from multiple places, doing the same thing.

So now to perform an efficient update, React does the batching thing by extracting all the objects passed to each setState() call, merges them together to form a single object, then uses that single object to do setState(). According to the setState() documentation:

This form of setState() is also asynchronous, and multiple calls during the same cycle may be batched together. For example, if you attempt to increment an item quantity more than once in the same cycle, that will result in the equivalent of:

Object.assign(
  previousState,
  {quantity: state.quantity + 1},
  {quantity: state.quantity + 1},
  ...
)

Subsequent calls will override values from previous calls in the same cycle, so the quantity will only be incremented once. If the next state depends on the current state, we recommend using the updater function form, instead:

this.setState((state) => {
  return {quantity: state.quantity + 1};
});

For more detail, see:

setState() - Other APIs - React.Component – React.

So if any of the objects contains the same key, the value of the key of the last object with same key is stored. And hence the update only happens once with the last value.

Demo Codesandbox

这篇关于何时使用函数式 setState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆