react 关于this.setState使用时,第一次没法获取数据,第二次获取的数据是第一次触发的疑问

我使用的是antd组件,html

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中对应的变量里,可是在触发事件时,出现了第一次点击的时候并无将数据传递进去,在第二次点击的时候将第一次的数据传递进去了,这个问题该如何解决?react

 

4个回答

0

已采纳

setState其实并非异步的,它在整个执行过程当中没有任何的setTimeout或者promise等异步操做。git

你能够尝试下在setTimeout(或者本身绑定的DOM事件,可是不要在JSX中绑定事件哦,要本身手动addEventListener,目的就是摆脱React的控制)中调用setState(newState)方法,而后紧接着log看下你设置的新的state有没有起做用呢?若是再仔细一些,你还能够研究下此次的setState、render、log的执行顺序是怎样的呢?github

不要被setState的名字欺骗了,它实际上是 set pending state —— 将你传入的newState放入一个待更新的队列,到此为止你的setState方法基本已经完成了它全部的工做。算法

真正执行state合并更新的另有其人 —— transaction,对于React的transaction网上有相应的讲解,在这里再也不赘述,有兴趣能够看下Transaction源码以及ReactUpdates源码segmentfault

setTimeout中setState和在生命周期里setState的区别在于,setTimeout中的setState会本身触发一个transaction,而生命周期中的setState已经处于React生命周期的transaction中了。promise

最后:若是想在newState起效后执行一些处理,最好仍是放在setState的回调中哦antd

2

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...async


如下是补充"为什么说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实际被完成时被执行。

0

和 antd 不要紧。

setState 是异步的:https://facebook.github.io/re...

0

在setState回调里写要作的事情

 

引用原文:https://segmentfault.com/q/1010000007343714

 

写博客是为了记住本身容易忘记的东西,另外也是对本身工做的总结,文章能够转载,无需版权。但愿尽本身的努力,作到更好,你们一块儿努力进步!

若是有什么问题,欢迎你们一块儿探讨,代码若有问题,欢迎各位大神指正!

相关文章
相关标签/搜索