react 关于this.setState使用时,第一次无法获取数据,第二次获取的数据是第一次触发的疑问
我使用的是antd组件,
compareClickFn(orderCodes, fileNames) {
printLog("orderCodes----------"+ orderCodes);
printLog("fileNames----------"+ fileNames);
this.setState({
show: !this.state.show,
orderCode: orderCodes,
fileName: fileNames,
});
printLog("orderCode and fileName------"+ this.state.show + "----" + this.state.fileName);
const ShowAnim = document.getElementById('ShowAnim');
if (this.state.show === false) {
ShowAnim.style.display = 'block';
this.state.type = 'primary';
} else {
ShowAnim.style.display = 'none';
this.state.type = 'ghost';
}
}
这段代码是<Button>组件的onclick事件函数,其中orderCoder和fileName已经获取到了,我想要将这些值保存进入this.state中对应的变量里,但是在触发事件时,出现了第一次点击的时候并没有将数据传递进去,在第二次点击的时候将第一次的数据传递进去了,这个问题该如何解决?
4个回答
setState其实并不是异步的,它在整个执行过程中没有任何的setTimeout或者promise等异步操作。
你可以尝试下在setTimeout(或者自己绑定的DOM事件,但是不要在JSX中绑定事件哦,要自己手动addEventListener,目的就是摆脱React的控制)中调用setState(newState)方法,然后紧接着log看下你设置的新的state有没有起作用呢?如果再仔细一些,你还可以研究下这次的setState、render、log的执行顺序是怎样的呢?
不要被setState的名字欺骗了,它其实是 set pending state —— 将你传入的newState放入一个待更新的队列,到此为止你的setState方法基本已经完成了它所有的工作。
真正执行state合并更新的另有其人 —— transaction,对于React的transaction网上有相应的讲解,在这里不再赘述,有兴趣可以看下Transaction源码以及ReactUpdates源码
setTimeout中setState和在生命周期里setState的区别在于,setTimeout中的setState会自己触发一个transaction,而生命周期中的setState已经处于React生命周期的transaction中了。
最后:如果想在newState起效后执行一些处理,最好还是放在setState的回调中哦
this.setState是异步的,所以你一呼叫this.setState完,马上作获取this.state中的值,不一定能获取得到改变的值。
1. 用this.setState的第二参数,给一个回调来在更新后执行,例如:
this.setState({ something: true }, () => console.log(this.state))
2. 用componentDidUpdate()这个生命周期方法,把确定更新后要作的代码放里面。
3. mobx有神奇的@observer与@observable可以作这事。
@observer class Select extends React.Component {
@observable selection = null; /* MobX managed instance state */
constructor(props, context) {
super(props, context)
this.selection = props.values[0]
}
//...
上面代码取自这篇文章的里: https://medium.com/@mweststra...
以下是补充"为何说setState是异步的?"的回答
setState并非使用setTimeout或promise的那种进入到事件回圈(Event loop)的异步执行,但它的执行行为在React库中控制时,的确是异步的。以最精确的说法来说,"它不是保证同步的",官方的说明也是如此。
setState包含在其中执行过程是一个很复杂的过程,从最初的版本到现在,也有无数次的修改。它的工作除了要设定this.state之外,还要负责触发重渲染,这里面需要经过React核心中演算法,也就是virtual DOM的演算,最终才能决定是否要进行重渲染,以及如何渲染。为了批次与效能的理由,多个setState呼叫有可能在过程中要进行合并,所以它被设计以异步来执行是合理的,但这主要限于在React库的控制之中。
那么setState会在何时以同步的方式来执行,也就是立即更动this.state?答案是在React函式库控制之外时,它就会以同步的方式来执行,在下面两篇文章中,都有类似的例子:
但大部份的使用情况下,我们都是使用了React库中的表单控件,例如select, button,这些是React库中人造的控件与事件,是处于React库的控制之下,setState就会以异步的方式执行。所以一般来说,我们会认为setState就是异步执行,并不是用源代码来看说它是不是有使用setTimeout或Promise之类的方式转为JS的异步执行方式,而是以它在React库的控制之下,以执行行为与顺序来理解。
以下是翻译自官方setState源码的注解,其实如果是官网的说明也是类似的说明:
不保证
this.state会立即更新,所以在调用这个方法后存取this.state可能会回传旧的值。不保证调用
setState就会同步地执行,而它们也可能最终被被批量调用(多次调用的情况下)。你可以提供额外的回调,回调将会在setState实际被完成时被执行。
和 antd 没关系。
setState 是异步的:https://facebook.github.io/re...
在setState回调里写要做的事情
引用原文:https://segmentfault.com/q/1010000007343714
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权。希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!
react 关于this.setState使用时,第一次无法获取数据,第二次获取的数据是第一次触发的疑问的更多相关文章
- jqueryUI中datepicker的使用,解决与asp.net中的UpdatePanel联合使用时的失效问题
1.jqueryUI的datepicker的使用 -->首先在jqueryUI官网上根据你的需要下载适合你系统主题的样式,jqueryUI主题下载地址: -->下载后的文件 jquery- ...
- [React技术内幕] setState的秘密
对于大多数的React开发者,setState可能是最常用的API之一.React作为View层,通过改变data从而引发UI的更新.React不像Vue这种MVVM库,直接修改data并不能视图的改 ...
- Cookie使用时需要注意个数及大小限制
各浏览器对Cookie有一定的限制,在使用时需要格外注意. 各浏览器之间对cookie的不同限制: IE6.0 IE7.0/8.0/9.0+ Opera FF Safari Chrome cook ...
- EntityFrameWork 使用时碰到的小问题
EntityFrameWork 使用时碰到的小问题 1,在使用orm访问数据库的相目里,也要引用EntityFrameWork.dll,否则无法使用orm 否则,编译错误 错误 5 "Sys ...
- MySQL 安装和启动服务,“本地计算机 上的 MySQL 服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止。”
MySQL 安装和启动服务,以及遇到的问题 MySQL版本: mysql-5.7.13-winx64.zip (免安装,解压放到程序文件夹即可,比如 C:\Program Files\mysql-5. ...
- MaterialCalendarView使用时遇到的问题
一.概述 MaterialCalendarView是一个开源项目.功能强大支持多选.单选.标注等. 二.问题 1.其继承自ViewGroup,故与CalendarView半毛钱关系都没有,完全是一个新 ...
- [备忘][转]rsync使用时的常见问题
sync使用时的常见问题: 错误1: rsync: read error: Connection reset by peer (104) rsync error: error in rsync pro ...
- 小白学数据分析----->移动游戏的使用时长分析
写下该文章,是因为之前看到了几款游戏一个典型的玩家刺激活动,在<多塔联盟>,<萌江湖>等多款游戏的设计中都有体现,如下图所示: 这个功能点的设计,今天在这里讲的更多的还是跟数据 ...
- VS2010 使用时选择代码或双击时出错,点击窗口按钮后VS自动重启问题
VS2010 使用时选择代码或双击时出错崩溃,点击窗口按钮后VS自动重启问题 下载补丁,打上补丁之后,重启电脑,解决了问题. WindowsXP的下载地址:Windows XP 更新程序 (KB971 ...
随机推荐
- java获取系统时区
//Calendar cal = Calendar.getInstance(); //TimeZone timeZone = cal.getTimeZone(); TimeZone timeZone ...
- Laravel5.1 模型 --多态关联
什么是多态关联? 一个例子你就明白了:好比如说评论 它可以属于视频类 也可以属于文章类,当有个需求是 从评论表中取到视频类的数据,这就需要用到多态关联了. 简单的一句话总结:一张表对应两张表. 1 实 ...
- Integer自动装拆箱
public static void main(String[] args) { Integer a1 = 1; Integer a2 = 1; Integer b1 = 127; Integer b ...
- 1.0_搭建PHP服务器环境的步骤
a,下载安装一款静态web服务器,ex:HTTPD,IIS; b,下载安装PHP引擎: c,在静态服务器配置一下,声明PHP引擎的存在. 注意,以上三步可以用xampp套件来完成. 启动Apache, ...
- iOS侧面加shadow
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:_bgView.bounds]; _bgView.layer.masksToBo ...
- 存一些可能会用得到的vue的UI框架
VUX 项目主页:https://vux.li/#/ github地址:https://github.com/airyland/vux element UI(饿了么后台) Element 是由饿了么U ...
- 网站漏洞扫描工具(appscan,mdcsoft-ips)
网站漏洞扫描工具:主要应用网站漏洞扫描工具,其原理是通过工具通过对网站的代码阅读,发现其可被利用的漏洞进行告示,通过前人收集的漏洞编成数据库,根据其扫描对比做出. 具体网站扫描工具有:appscan, ...
- 如何cancel掉慢查询
百度Elasticsearch-产品描述-介绍-百度云 https://cloud.baidu.com/doc/BES/FAQ.html#.E5.A6.82.E4.BD.95cancel.E6.8E. ...
- <2014 05 16> 线性表、栈与队列——一个环形队列的C语言实现
栈与队列都是具有特殊存取方式的线性表,栈属于先进后出(FILO),而队列则是先进先出(FIFO).栈能够将递归问题转化为非递归问题,这是它的一个重要特性.除了FILO.FIFO这样的最普遍存取方式外, ...
- 面试常见的selenium问题
1.如何切换iframe 问题:如果你在一个default content中查找一个在iframe中的元素,那肯定是找不到的.反之你在一个iframe中查找另一个iframe元素或default co ...
