react 中,setState 是同步还是异步更新数据?

282 阅读2分钟

前言

为了验证 react 中, setState 到底是同步还是异步更新数据,咱们开启一个小项目测试一番!

一、项目准备工作

  • npx create-react-app react-setstate
  • cd react-setstate
  • yarn start 或 npm start 或 npm run start
  • 新建 src/components/ComSetState.js

image.png

二、index.js 入口

import React from 'react'
import ReactDOM from 'react-dom'

import App from './App'

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
)

三、App.js 导入组件

import React from 'react'
// 导入 ComSetState 组件
import ComSetState from './components/ComSetState'
class App extends React.Component {
  render() {
    return <div>
      <ComSetState></ComSetState>
    </div>
  }
}
export default App

四、ComSetState.js 测试(1)

1、上代码(使用 react 事件,通过 this.setState 修改 state 中的数据)

import React from 'react'
// ◆验证 setState 是同步还是异步?
class ComSetState extends React.Component {
    state = {
        count: 1
    }
    addHandler = () => {
        console.log(this.state.count, 'setState之前111')
        this.setState({
            count: this.state.count + 1
        })
        // 注意:setState 写成箭头函数的方式:参数可以获取 state 中的原始数据
        // this.setState((params)=>{
        //     console.log(params,999);
        //     return {
        //         count:this.state.count+1
        //     }
        // })
        console.log(this.state.count, 'setState之后222')
    }
    render() {
        console.log(this.state.count, 'render333');
        return <div>
            我是 ComSetState 组件
            <p>数量:{this.state.count}</p>
            <button id="btn" onClick={this.addHandler}>++1</button>
        </div>
    }
}
export default ComSetState

2、分析控制台打印结果

image.png

由此可见

  • 进入页面,render 会首先渲染
  • 点击按钮加 1 ,先打印 setState之前111,后打印 setState之后222,最后打印 render333
  • 显而易见,是异步更新数据:优先执行同步任务,碰到异步修改数据的任务,会先放到任务队列中
  • 所以使用 react 事件,setState 是异步更新数据的

五、ComSetState.js 测试(2)

1、上代码(使用 原生 事件,通过 this.setState 修改 state 中的数据)

import React from 'react'
// ◆验证 setState 是同步还是异步?
class ComSetState extends React.Component {
    state = {
        count: 1
    }
    //  componentDidMount 相当于 Mounted
    componentDidMount() {
        document.querySelector('#btn').addEventListener('click', () => {
            console.log(this.state.count, 'setState之前111')
            this.setState({
                count: this.state.count + 1
            })
            console.log(this.state.count, 'setState之后222')
        })
    }
    render() {
        console.log(this.state.count, 'render333')
        return <div>
            我是 ComSetState 组件
            <p>数量:{this.state.count}</p>
            <button id="btn" onClick={this.addHandler}>++1</button>
        </div>
    }
}
export default ComSetState

2.分析控制台打印结果

image.png

由此可见

  • 进入页面, render 会首先渲染
  • 点击按钮加 1 ,先打印 setState之前111,后打印 render333,最后打印 setState之后222
  • 显而易见,是同步更新数据:从上至下,依次执行
  • 所以使用 原生 事件,setState 是同步更新数据的