javascript - 何时使用函数式 setState

标签 javascript html reactjs

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

例如,假设我有一个包含以下内容的类(class):

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>
       }
    }
}

在这个示例中,我从 API 获取图像。

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

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

我见过它以两种不同的方式编写:

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

this.setState({图片: pics})

2) 这更复杂,但我看到它被描述为一种更安全的方法

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

有人可以解释一下使用其中任何一个的优点吗?我希望将来与代码保持一致,处理 props 和 states 等,所以最通用的方法当然是首选。

最佳答案

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

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

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

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

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

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

考虑一个简单的情况,为了理解这一点,在您的函数中,您可以多次调用 setState() ,如下所示:

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)})

   ...
}

这在简单的应用程序中不是有效的用例,但随着应用程序变得复杂,多个 setState() 调用可能会从多个位置发生,执行相同的操作。

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

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.

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

<强> Demo Codesandbox

关于javascript - 何时使用函数式 setState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50021892/

相关文章:

javascript - 以 Angular 4 过滤给定数组而不使用另一个数组并将其显示在同一组件中

javascript - 使用 jade 和 Eclipse 出现意外 token 'Indent'

jquery - 如何从多个 HTML 元素的特定起点和终点使用 jQuery .wrap()?

javascript - React 状态不会重新渲染

javascript - addthis:addthis 实用程序框架的 JS 安全错误

javascript - 在 Mobile Safari 中预加载 HTML5 音频

javascript - 如何知道是否选中具有特定 id 的单选按钮以在 if else 语句中使用

java - 为什么IE文档模式在一个环境下是Edge,在另一个环境下是IE5

javascript - 冲突事件 : onKeyPress & onClick

javascript - 如何禁用手机上出现的键盘 : React date time picker