setState跟新数据是同步还是异步?

setState跟新数据是异步的。
如何用代码表现出来是异步的。
点击按钮更新数据,然后去打印这个值看一下

setState跟新数据是异步的

class Father extends React.Component{
state = {
num:0
}
addHandler = () => {
this.setState({
num: 100
})
console.log('state中的值',this.state.num)
}
render() {
return (
<div>
<button onClick={this.addHandler}>新增</button>
<p>显示的值 {this.state.num }</p>
</div>
)
}
}
ReactDOM.render(
<Father></Father>,
document.getElementById('root')
)

我们发现

当我们使用setState更新数据时候,
然后立刻去获取更新后的值,我们发现不是我们更新后的值。
而是更新前的值。
这就说明了setState跟新数据是异步的

因此需要注意的点

由于 setState 跟新数据是异步的。
因此 setState 后面的代码不要依赖于setState前面的。

同一个方法多次调用 setState会怎么样

class Father extends React.Component{
state = {
num:0
}
addHandler = () => {
<!-- 第一调用 -->
this.setState({
num: this.state.num+1
})
console.log('state中的值', this.state.num) <!-- 第二次调用 -->
this.setState({
num: this.state.num + 1
})
console.log('state中的值', this.state.num)
}
render() {
return (
<div>
<button onClick={this.addHandler}>新增</button>
<p>显示的值 {this.state.num }</p>
</div>
)
}
}

我们的结论

在同一个方法中我们调用了两次setState.
但是最后界面上显示的不是2;0+1+1=2
而是显示的1
也就是说虽然多次调用setState,但是最终只会执行一次。
所以只会触发一次渲染界面。所以界面上显示的是1
由于界面只触发一次,所以render函数也只会触发一次

为什么多次调用setState最终只会触发一次渲染界面

这样做的目的是为了性能的考虑。
比如说你写了一个循环,循环了1000次;
设计的时候如果让setState执行1000次;
这样太浪费性能了。
完全可以让开发者将最后的结果进行展示。 所以React并不会将setState执行1000次
而是只会执行一次。 render函数也只会执行一次。

非要让setState多次执行怎么办?

有没有这样的场景?
第二次的setState需要依赖第一次的setState的结果
举个简单的例子:第一次数字从0变为1,第二次1变为10
这个时候我们怎么办了?
比着急,有解决的办法

setState 推荐语法

setState((state, props) => {
参数state,表示最新的state
参数props,表示最新的props
})
需要的是这种语法也是异步的哈

使用推荐语法实现setState多次执行

class Father extends React.Component{
state = {
num:0
}
addHandler = () => {
<!-- 在这个方法中我们多次调用了setState -->
this.setState((state, props) => {
// state
// props
return {
num: state.num+1
}
})
this.setState((state, props) => {
// state
// props
return {
num: state.num + 10
}
})
console.log('state中的值', this.state.num)
}
render() {
return (
<div>
<button onClick={this.addHandler}>新增</button>
<p>显示的值 {this.state.num }</p>
</div>
)
}
}

setState第二个参数的诞生

刚刚我们在前面发现console.log获取的值
不是数据更新的后的值。
而是初始值。我们也说了
由于 setState 跟新数据是异步的。
因此 setState 后面的代码不要依赖于setState前面的。
如果我们想获取 setState更新后的值怎么办了?
这个时候我们就需要使用setState的第二个参数。 setState第二个参数的场景
在状态更新完成(界面完成重新渲染)后立刻执行某一个操作
ps:需要注意的的是不可以不会页面中的dom
ps:需要注意的的是不可以不会页面中的dom
this.setState(
(state, props) => {
return {}
},
()=>{
console.log('界面完成重新渲染)后立刻执行某一个操作')
}
)

setState第二个参数的使用

class Father extends React.Component{
state = {
num:0
}
addHandler = () => {
this.setState(
(state, props) => {
return {
num: state.num + 1
}
},
() => {
console.log('获取setState跟新后的值', this.state.num)
console.log('dom节点',document.getElementById('#name') )
console.log('cont', document.title)
}
)
}
render() {
return (
<div>
<button onClick={this.addHandler}>新增</button>
<p id='name'>显示的值 {this.state.num }</p>
</div>
)
}
}
ReactDOM.render(
<Father></Father>,
document.getElementById('root')
)

React中setState方法说明的更多相关文章

  1. React中setState学习总结

    react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步. 1.先来回顾一下react组件中改变state的几种方式: import React, { Compone ...

  2. 理解React中es6方法创建组件的this

    首发于:https://mingjiezhang.github.io/(转载请说明此出处). 在JavaScript中,this对象是运行时基于函数的执行环境(也就是上下文)绑定的. 从react中的 ...

  3. React中setState的怪异行为 ——setState没有即时生效

    setState可以说是React中使用频率最高的一个函数了,我们都知道,React是通过管理状态来实现对组件的管理的,当this.setState()被调用的时候,React会重新调用render方 ...

  4. React中setState同步更新策略

    setState 同步更新 我们在上文中提及,为了提高性能React将setState设置为批次更新,即是异步操作函数,并不能以顺序控制流的方式设置某些事件,我们也不能依赖于this.state来计算 ...

  5. React中setState如何修改深层对象?

    在React中经常会使用到setState,因为在react生态中,state就是一切.在开发过程中,时长会在state中遇到一些比较复杂的数据结构,类似下面这样的: 这时需要我们修改list中obj ...

  6. React中setState 什么时候是同步的,什么时候是异步的?

    class Example extends React.Component { constructor() { super(); this.state = { val: 0 }; } componen ...

  7. react中setState用法

    setState()更新状态的2种写法 setState(updater, [callback]), updater为返回stateChange对象的函数: (state, props) => ...

  8. React中setState注意事项

    setState是一个异步函数,异步获取数据 学习react在使用ref和setState操作DOM时会遇到的问题: ref获取ul结点元素 错误写法:得到的ul长度总是上一次输入后的长度 结果: 正 ...

  9. 「React Native笔记」在React的 setState 中操作数组和对象的多种方法(合集)

    运用在React 中 setState的对象.数组的操作时是不能用类似array.push()等方法,因为push没有返回值,setState后会出现state变成Number,为了方便他人和自己查看 ...

随机推荐

  1. 学习打卡day12&构建之法阅读笔记第一篇

    今天浅读了<构建之法>的前四章,稍微有一些个人的见解与感受 第一点即是开篇提及到的算法与数据结构这门学科开设的必要,大二上学期学习了这门课程,就我个人目前接触到的层面来看,几乎可以说用不太 ...

  2. acwing刷题-放养又没有完全放养

    题目 一个鲜为人知的事实是,奶牛拥有自己的文字:「牛文」. 牛文由 26 个字母 a 到 z 组成,但是当奶牛说牛文时,可能与我们所熟悉的 abcdefghijklmnopqrstuvwxyz 不同, ...

  3. 2021.11.03 P6175 无向图的最小环问题

    2021.11.03 P6175 无向图的最小环问题 P6175 无向图的最小环问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 给定一张无向图,求图中一个至少包含 33 ...

  4. 如何使用 Redis 缓存

    如何使用 Redis 缓存 前言 旁路缓存 只读缓存 读写缓存 设置多大的缓存合适 内存被写满了如何处理 缓存经常遇到的问题 1.缓存中的数据和数据库中的不一致 读写缓存 只读缓存 来个异常的栗子 1 ...

  5. 3.5 常用Linux命令

    1.touch命令 touch命令用于创建空白文件或设置文件的时间,语法格式为"touch [参数] 文件名称". 2.mkdir命令 mkdir命令用于创建空白的目录,英文全称为 ...

  6. React 父组件调用子组件的方法

    父组件调用子组件的方法 React v16.3.0 及以后版本使用 import React, {Component} from 'react'; export default class Paren ...

  7. Linux磁盘和文件系统知识总结

    硬盘操作 为什么要给硬盘分区? 如果你需要在一块硬盘上用到多个文件系统,那么你就需要对硬盘进行分区,以便用不同的分区支持不同的文件系统.(但一个硬盘只能有一个分区表!)反过来说,如果你整块硬盘都用同样 ...

  8. ZIP压缩输入/输出

    学习内容: 一.压缩文件 1.利用ZipOutputStream类对象,可将文件压缩. 2.ZipOutputStream类构造方法:ZipOutputStream(OutputStream out) ...

  9. elemetnUI表格分别给列表每一个按钮加loading

    // 获取列表数据的时候--添加按钮loading this.list = this.list.map((item) => { this.$set(item, "dataLoading ...

  10. NBMiner42.1版本发布,完全解锁30系LHR版本显卡

    2021年下半年,NVIDIA发布了LHR版本显卡,对显卡算力进行了限制. 2022年5月8日,NBMiner发布NBMiner_41.0版本,在最新的内核中加入了100%LHR解锁器,适用于Wind ...