state.type = 'ghost';
这段代码是<Button>组件的onclick事件函数,其中orderCoder和fileName已经获取到了,我想要将这些值保存进入this.state中对应的变量里,但是在触发事件时,出现了第一次点击的时候并没有将数据传递进去,在第二次点击的时候将第一次的数据传递进去了,这个问题该如何解决?
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;
上面代码取自这篇文章的里: https://medium.com/@mweststra...
以下是补充"为何说setState是异步的?"的回答
setState
并非使用setTimeout或promise的那种进入到事件回圈(Event loop)的异步执行,但它的执行行为在React库中控制时,的确是异步的。以最精确的说法来说,"它不是保证同步的",官方的说明也是如此。
setState
包含在其中执行过程是一个很复杂的过程,从最初的版本到现在,也有无数次的修改。它的工作除了要设定this.state
之外,还要负责触发重渲染,这里面需要经过React核心中演算法,也就是virtual DOM的演算,最终才能决定是否要进行重渲染,以及如何渲染。为了批次与效能的理由,多个setState呼叫有可能在过程中要进行合并,所以它被设计以异步来执行是合理的,但这主要限于在React库的控制之中。
那么setState会在何时以同步的方式来执行,也就是立即更动this.state
?答案是在React函式库控制之外时,它就会以同步的方式来执行,在下面两篇文章中,都有类似的例子:
http://thereignn.ghost.io/on-...
https://www.bennadel.com/blog...
但大部份的使用情况下,我们都是使用了React库中的表单控件,例如select, button,这些是React库中人造的控件与事件,是处于React库的控制之下,setState
就会以异步的方式执行。所以一般来说,我们会认为setState
就是异步执行,并不是用源代码来看说它是不是有使用setTimeout或Promise之类的方式转为JS的异步执行方式,而是以它在React库的控制之下,以执行行为与顺序来理解。
以下是翻译自官方setState源码的注解,其实如果是官网的说明也是类似的说明:
不保证this.state
会立即更新,所以在调用这个方法后存取this.state
可能会回传旧的值。
不保证调用setState
就会同步地执行,而它们也可能最终被被批量调用(多次调用的情况下)。你可以提供额外的回调,回调将会在setState
实际被完成时被执行。
引用原文:https://segmentfault.com/q/1010000007343714
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权。希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!