React学习笔记15-setState同步异步问题
1.React学习笔记01-React的基本认识2.React学习笔记02-创建React项目3.React学习笔记03-编写第一个react应用程序4.React学习笔记04-JSX语法5.React学习笔记05-类组件6.React学习笔记06-函数式组件7.React学习笔记07-组件嵌套8.React学习笔记08- 组件的样式9.React学习笔记09- 事件处理10.React学习笔记10- Ref的应用11.React学习笔记11-状态(state)12.React学习笔记12-循环渲染13.React学习笔记13-小案例toList(状态,状态维护,条件渲染渲染)14.React学习笔记14-dangerousSetinnerHtml指令
15.React学习笔记15-setState同步异步问题
16.React学习笔记16-属性props17.React学习笔记17-属性VS状态18.React学习笔记18-非受控组件19.React学习笔记19-受控组件20.React学习笔记20-父子通信(子传父)21.React学习笔记21-非父子通信(状态提升)22.React学习笔记22-订阅发布模式23.React学习笔记23-非父子通信(订阅发布模式)先说结论:
setState处在同步的逻辑中会异步更新状态,更新真实dom。
连续调用 setState 不会连续进行虚拟dom的对比和页面的更新
setState处在异步的逻辑中,同步更新状态,更新真实dom。
1.同步状态
先看同步状态
/* eslint-disable react/no-direct-mutation-state */ import React, { Component } from 'react' export default class App extends Component { state = { count: 1 } render() { return ( <div> <div>{this.state.count}</div> <button onClick={ () => {
this.setState({
count: this.state.count + 1
})
console.log(this.state.count)
this.setState({
count: this.state.count + 1
})
console.log(this.state.count)
this.setState({
count: this.state.count + 1
})
} }>add1</button> </div> ) } }
可以看出来三个打印都是1,说明setState在同步环境下是异步进行更新的
并且执行了三次setState实际上只更新了一次dom
这是因为
react会根据是同步队列还是异步队列来指定一个来决定setState是否合并处理的标志位,
同步队列为true,
这时setState会异步执行,进行合并处理,
因为跟新的都是同一个状态所以会
合并为 this.setState({
count: this.state.count + 1
})
连续调用只会更新一次dom
2.同步状态下,如何获取dom更新后的state
/* eslint-disable react/no-direct-mutation-state */ import React, { Component } from 'react' export default class App extends Component { state = { count: 1 } render() { return ( <div> <div>{this.state.count}</div> <button onClick={ () => { // this.setState的第二个参数是一个函数, //可以看做状态更新和dom后的回调 this.setState({ count: this.state.count + 1 }, () => { console.log(this.state.count) }) this.setState({ count: this.state.count + 1 }, () => { console.log(this.state.count) }) this.setState({ count: this.state.count + 3 }, () => { console.log(this.state.count) }) /* 同步逻辑下,在setState的回调中可以打印出更新后的状态。这里因为是 合并处理,所以以最后一个为准,打印出来是1+3 = 4 */ } }>add1</button> </div> ) } }
如果在同步情况下想要获取dom更新后的state可以通过setState的第二个参数来获取
this.setState的第二个参数是一个函数,可以看做状态更新和dom后的回调
同步逻辑下,在setState的回调中可以打印出更新后的状态。这里因为是
合并处理,所以以最后一个为准,打印出来是1+3 = 4
3.异步状态
/* eslint-disable react/no-direct-mutation-state */ import React, { Component } from 'react' export default class App extends Component { state = { count: 1 } render() { return ( <div> <div>{this.state.count}</div> <button onClick={ () => { setTimeout(() => { //异步逻辑 this.setState({ count: this.state.count + 1 }) console.log(this.state.count) this.setState({ count: this.state.count + 1 }) console.log(this.state.count) this.setState({ count: this.state.count + 1 }) console.log(this.state.count) }, 0); } }>add</button> </div> ) } }
可以看到在异步状态下setState是同步调用的每次更新状态都会被打印下来,并且同步会更新状态和dom
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix