# 【拓展】 react 中的 setState

96 阅读4分钟

【拓展】 react 中的 setState

在之前博客中说过 【 react 使用 state 】,其实这一小部分算是那一篇博文的拓展吧!关于修改状态值的相关知识点,但是不是太难的部分,稍微提一嘴。

案例

还是习惯性的以案例开始,我们实现一个简单的案例,写一个组件,这个组件有啥用呢?很简单,点击按钮,数据 +1,然后数据在页面上显示一下。就是下面这个样子:

在这里插入图片描述 OK,这个案例在之前博客写了无数遍了,都写烂了,只把关键代码贴进来啦哈!

import React, { Component } from 'react';

export default class Demo extends Component {

  state = { count: 0 }

  add = () => {
    const { count } = this.state
    this.setState({ count: count + 1 })
  }

  render() {
    return (
      <div>
        <h2>当前的数据为:{this.state.count}</h2>
        <button onClick={this.add}>点我+1</button>
      </div>
    );
  }
}

好,就是上面这段代码,点击按钮执行 add 方法,add 方法中,首先获取当前状态的 count 值,然后通过 setState 方法更新 count 数据值,实现 count 数据 +1 操作。

对象式的 setState

我们上面的案例和之前博客写的 setState 都是使用的对象式 setState。因为 setState 里面确实传递了一个对象进去的吧!

然后有一个经典的面试题 【请问:react 中 setState() 是同步的还是异步的?】

要想知道是同步的还是异步的,我们打印一下看看就可以了。

  add = () => {
    const { count } = this.state
    this.setState({ count: count + 1 })
    console.log("执行完成", this.state.count)
  }

代码是从上往下依次执行,那好,this.setState({ count: count + 1 }) 是来实现对 count + 1 操作的代码,执行完我们在下面打印,应该打印出最新的数据对吧?我们刷新页面,只点击一次,页面应该展示1,控制台应该打印1 就对了,看效果:

在这里插入图片描述

这个效果就很明显了把,setState() 是一个异步的,它自身会立即执行,但是他里面 react 操作 state 数据的动作确实异步的,所以说可以理解成 setState() 就是一个异步的方法。

那我们怎么来打印一下更新后的数据呢?很简单,异步操作,一般都有回调函数的,其实 setState() 是有异步函数的,但是呢,我们之前一直没有用。

  add = () => {
    // 对象式的 setState
    const { count } = this.state
    this.setState({ count: count + 1 }, () => {
      console.log("执行完成", this.state.count)
    })
  }

我们除了 状态改变对象 之外,写一个回调函数,在回调函数里面打印一下 count 的数据:

在这里插入图片描述

诶,现在数据就对了吧!so,这个回调是在什么时候会被调用呢?它在状态更新完毕、界面也更新后(render调用后)才被调用。

函数式的 setState

啊哈哈哈哈哈!除了对象式的 setState 之外,还有 函数式的 setState ,这个之前的博客从来没有说过,然后呢简单说一下,使用函数式 setState 的时候,我们传递的不再是一个对象,而是一个函数,函数可以接收两个参数,第一个参数是 state,第二个参数是 props,这个函数要求返回 状态改变对象

我们把上面的案例使用 函数式 setState 写一下子,其实也很简单,然后我们在使用这个组件的时候传递一个 name ,然后主要是看看 props 能不能接收到。

<Demo name="𝒆𝒅." />
  add = () => {
    // 函数式的 setState
    this.setState((state, props) => {
      console.log('====>>> ', state, props)
      return { count: state.count + 1 }
    })
  }

然后我们点击看一下效果哈!

在这里插入图片描述

OK,看到效果是和以前一模一样的,点击按钮也可以正常获取到 stateprops。当然,函数式 setState 也是有回调函数的,和 对象式 setState 是一样用的,都是可选的,想用就用回调,不想用就不用,它的回调也是在状态更新、界面也更新后(render调用后)才被调用。

然后很多宝子可能会问了,在什么时候使用函数式的,什么时候使用对象式的?其实哈,这个没有具体的标准,你喜欢用啥就用啥,我这里为啥说一下,是怕我们之前一直使用的是对象式的,从来没有提到过函数式,如果实际开发过程中遇到别人写的函数式的,怕我们当场懵掉。

总结

  • setState(stateChange, [callback]) 对象式的setState
    • stateChange为状态改变对象(该对象可以体现出状态的更改)
    • callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用
  • setState(updater, [callback]) 函数式的setState
    • updater为返回stateChange对象的函数。
    • updater可以接收到state和props。
    • callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。

对象式的 setState 是函数式的 setState 的简写方式 (语法糖)

使用原则: - 如果新状态不依赖于原状态 -----> 使用对象方式。 - 如果新状态依赖于原状态 -----> 使用函数方式。 - 如果需要在setState()执行后获取最新的状态数据,要在第二个callback函数中读取。

【本博文相关代码资料】:我是𝒆𝒅. 的 gitee

好了,今天的内容就到这里,拜拜啦各位宝子们~~

在这里插入图片描述