React-setState的那些事儿
关于setState,使用过react的人应该再熟悉不过了,在hooks还不那么普及的时候,除了使用函数式组件,我们使用最多的应该就是类创建react的组件了,而在类组件中我们通常会使用state来管理组件的数据变化及更新。
setState的使用注意事项
setState(updater, callback)
这个方法是用来告诉react组件数据更新渲染。
在使用setState
改变状态之后,立刻通过this.state
去拿最新的状态往往可能并不容易拿到的。
要点1:
基于此如果需要拿到最新的state,根据官方给的方法就是在‘componentDidUpdate或者在setState的第二个参数的回调函数中获取
componentDidMount(){
this.setState({
date: 3,
}, function(){
console.log('callback',this.state.date) // date为 3
});
console.log('fn',this.state.date) // date为1
}
要点2:
对于同时累加多次的问题
componentDidMount(){
this.setState({
date: this.state.date + 1,
});
this.setState({
date: this.state.date + 1,
});
this.setState({
date: this.state.date + 1,
});
}
// 最后date的值只累加了一次,为2
我们的目标值可能是4,但是react最后给出的与我们目标值不一样,这是因为react为了考虑性能问题,防止重复渲染将setState方法统一在渲染前统一进行,之后再进行render
如果想要得到4,推荐再setState传function
componentDidMount(){
this.setState((state) => {
return {date: state.date + 1}
});
this.setState((state) => {
return {date: state.date + 1}
});
this.setState((state) => {
return {date: state.date + 1}
});
} // 最后得到目标值4
那么setState是同步的还是异步的?
从上面我们发现当我们在setState后没法立即拿到我们设置的值,可能很多人想说,因为setState是异步的。情况真的是这样吗,看下面的例子
// 定时器中
componentDidMount(){
setTimeout(() => {
this.setState({
date: 2
});
console.log('1111', this.state.date) // date为2
})
} // 或者监听函数
componentDidMount(){
document.getElementById('button').addEventListener('click', this.clicks)
} clicks = () => {
this.setState({
date:3,
})
console.log('addEventListener', this.state.date); // date为3
}
我们发现在在定时器或者是监听函数等原生方法中时,当我们设置setState,我们是可以同步的拿到最新的state的值得。
而根据react源码,和我个人的理解setState是其实用同步的操作来模仿的异步的行为。
我们知道react为了兼容各种浏览器,同时为了性能的考量有自己的合成事件,譬如onClick、onChang之类的。当我们在生命周期中或者合成事件中,setState将变成异步的行为,而在js原生事件中setState将变成同步的。
那react是如何区分的呢,其实可以简单的理解为,react对于异步的setState会给方法打上一个isBatchingUpdates,并将它放在一个处理state的队列中,当react其他任务执行完需要开始渲染前,将循环处理队列中的方法,同时更新state
而对于同步的setState则进行直接更新。
参考
React-setState的那些事儿的更多相关文章
- 动态修改JS对象的值及React setState
一.在JS里使用(非ES6) 实现场景: 给一个空对象填充某一指定数组内的值 并随机生成数量 const fruit = ['apple', 'banana', 'orange'] let fruit ...
- 深入研究React setState的工作机制
前言 上个月发表了一篇 React源码学习--ReactClass,但是后来我发现,大家对这种大量贴代码分析源码的形式并不感冒.讲道理,我自己看着也烦,还不如自己直接去翻源码来得痛快.吸取了上一次的教 ...
- react组件通信那些事儿
父组件是调用组件的组件.现在看来,感觉父组件就是一个壳子,定义好壳子里面会有什么,而子组件是一个具体的实现,说明,会用到什么东西,如果有这些东西,会进行什么操作.总之,父组件是材料,有水和泥,子组件告 ...
- [Web 前端] 我不再使用React.setState的3个原因
copy from : https://blog.csdn.net/smk108/article/details/85237838 从几个月前开始,我在新开发的React组件中不再使用setState ...
- 关于React setState的实现原理(二)
React中的Transaction 大家学过sql server的都知道我们可以批量处理sql语句,原理其实都是基于上一篇我们说的Datch Update机制.当所有的操作均执行成功,才会执行修改操 ...
- 关于React setState的实现原理(三)
前面提到事务即将结束时,会去调用FLUSH_BATCHED_UPDATES的flushBatchedUpdates方法执行批量更新,该方法会去遍历dirtyComponents,对每一项执行perfo ...
- 关于React setState的实现原理(一)
前言 首先在学习react的时候就对setSate的实现有比较浓厚的兴趣,那么对于下边的代码,可以快速回答吗? class Root extends React.Component { constru ...
- react setState修改嵌套对象
在react使用setState过程中,难免会遇到复杂的数据类型,,这里还要提醒一下setState 是异步操作行为,需要setState之后的结果做为参数,请求数据的话,可以配合 async aw ...
- react setState里的作用域
从接触racet开始,我们就认识了setState,它是对全局变量进去更新的一个重要方法, 不仅可以更新数据,还能在更新后执行方法时直接调用刚刚更新的数据 今天碰到的问题就在于它的作用域的先后问题 先 ...
- React setState和修改props触发的钩子
1. setState的改变会触发4个生命周期钩子 shouldComponentUpdatecomponentWillUpdaterendercomponentDidUpdate 2. props的 ...
随机推荐
- Docker 实践搭建php环境
docker 安装 使用官方提供的安装脚本,安装最新版的Docker curl -sSL https://get.docker.com/ | sh 安装完成后,通过如下命令启动Docker的守护进程, ...
- 病毒木马查杀实战第023篇:MBR病毒之引导区的解析
前言 引导型病毒指寄生在磁盘引导区或主引导区的计算机病毒.这种病毒利用系统引导时,不对主引导区的内容正确与否进行判别的缺点,在引导系统的过程中入侵系统,驻留内存,监视系统运行,伺机传染和破坏.按照引导 ...
- 批处理打造MySQLCleaner
#批处理打造MySQLCleaner ###1. 简介 在我们卸载MySQL数据库的时候,往往除了需要卸载软件,还需要删除各种注册表信息,隐藏文件,卸载服务,否则当我们再次安装MySQL时就会出现一些 ...
- Linux内核升级、GRUB2引导故障处理与密码破解
目录 内核升级 GRUB2内核启动设置 GRUB2引导菜单加密 GRUB2引导故障及修复 救援模式管理 Rhel7破解root密码 内核升级 查看当前内核版本: uname -r 查看可升级内核: ...
- python中让输出不换行
Python2.x python2.x中输出默认是换行的,为了抑制换行,可以在打印最后加一个逗号 Python3.x 到了python3中,print 变成一个函数,这种语法便行不通了. 我们可以使用 ...
- POJ2431贪心(最少加油次数)
题意: 给一个终点,然后给你一个卡车距离终点的距离,还有其他个加油站距离终点的距离,然后每走一个单位距离要花费一个单位油,卡车的邮箱是无限大的,而每个加油站的油量是有限的,整个路径是一个 ...
- Photoshop 第二课 工具-钢笔的使用
钢笔的使用 钢笔→ 是一个非常实用(主要用于)但是非常难操作(会者不难哦~)的工具. 钢笔属性中有三种状态:1.路径:2.形状:3.像素.其中路径和形状是我们最常用的状态.路径是一条用来圈定需要操作的 ...
- 关于 C/C++ 函数调用约定
关于 C/C++ 函数调用约定,大多数时候并不会影响程序逻辑,但遇到跨语言编程时,了解一下还是有好处的. VC 中默认调用是 __cdecl 方式,Windows API 使用 __stdcall 调 ...
- PHP Tips
开启x_debug,使用var_dump()的显示效果会更好,同时错误也很更详细.
- 报错com.github.pagehelper.PageHelper cannot be cast to com.github.pagehelper.Dialect
报错com.github.pagehelper.PageHelper cannot be cast to com.github.pagehelper.Dialect spring以及mybatis版本 ...