-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Open
Labels
Description
1、第一次和第二次都是在 react 自身生命周期内,触发时 isBatchingUpdates 为 true,所以并不会直接执行更新 state,而是加入了 dirtyComponents,所以打印时获取的都是更新前的状态 0。
2、两次 setState 时,获取到 this.state.val 都是 0,所以执行时都是将 0 设置成 1,在 react 内部会被合并掉,只执行一次。设置完成后 state.val 值为 1。
3、setTimeout 中的代码,触发时 isBatchingUpdates 为 false,所以能够直接进行更新,所以连着输出 2,3。
输出: 0 0 2 3
wenJonSnow, xueqingxiao, AlanLang, jerryjiao, dushaobindoudou and 137 morealanwhy, MingWang04 and wadeewangcozyhana, mrandpz, NathanHan1, nbb321, jojomango and 4 moreallen3xiaokai, Wciel, Hoffylin, Battle-on, fearnliu and 5 more
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
zhanglin-doudou commentedon Feb 22, 2019
请问一下大佬,isBatchingUpdates的判断条件是什么呀?
mengsixing commentedon Feb 22, 2019
我理解的是:isBatchingUpdates 默认值为 false,当 react 自身的事件处理函数或 react 生命周期触发时,isBatchingUpdates 会被赋值为 true,当更新完成时又会被复原为 false。 @code-coder
azl397985856 commentedon Feb 22, 2019
#17
xueqingxiao commentedon Feb 22, 2019
具体可以见 ReactFiberScheduler 中的 performWork 和 performSyncWork。 楼主说的基本是对的,如果有这种 async 的 work 就不执行 batch update 如果没有 async 的就执行 batch update,setTimeout 和 promise 这些要进入 EventLoop 队列的都会被认为是 async work。
etsvain commentedon Feb 27, 2019
哦也我做对了
mochen666 commentedon Mar 5, 2019
@azl397985856 在React的setState函数实现中,会根据一个变量 isBatchingUpdate 来判断是直接同步更新this.state还是放到队列中异步更新 。React使用了事务的机制,React的每个生命周期和合成事件都处在一个大的事务当中。在事务的前置钩子中调用batchedUpdates方法修改isBatchingUpdates变量为true,在后置钩子中将变量置为false。原生绑定事件和setTimeout异步的函数没有进入到React的事务当中,或者当他们执行时,刚刚的事务已近结束了,后置钩子触发了,所以此时的setState会直接进入非批量更新模式,表现在我们看来成为了同步SetState。
[-]关于第19题的见解[/-][+]第 19 题:React setState 笔试题,下面的代码输出什么?[/+]AlertTed commentedon May 13, 2019
很好理解的问题 正常情况下 react是会同步更新数据的 也就是说isBatchingUpdate触发变成true 但是 如果你将state的状态值加入到setTimeout的延迟处理队列中 打印出来的值就是setState之后的值,或者你同时调用setState的第二个参数 也会做到异步操作 获取设置之后的state value
leonwens commentedon Jun 22, 2019
题目呢???
ggzcg commentedon Jul 15, 2019
做成了 0022 哎。竟然有isBatchingUpdates这种东西 学习了 @yhlben 。
allen3xiaokai commentedon Jul 24, 2019
我打印的 0 0 1 1
LastStranger commentedon Jul 27, 2019
react-hooks时代貌似改写了这种方式,我用react-hooks写法写出来的结果都是0
Bjkb commentedon Aug 23, 2019
@LastStranger
更新的方式没有更改,首先是因为useEffect函数只运行了一次,其次setTimeout是个闭包,访问到的值一直是0(按照正常的写法setVal(val+1))。以例子来看的话,并没有执行更新的操作。
具体可以参考 issue讨论: facebook/react#14010
27 remaining items