鍍金池/ 問答/HTML/ react16的異步渲染具體指哪里異步了?

react16的異步渲染具體指哪里異步了?

問題:react16實(shí)現(xiàn)了異步渲染,
1.這個(gè)異步渲染實(shí)現(xiàn)原理是啥?
2.跟vue的異步更新dom類似嗎?
在vue中如果數(shù)據(jù)發(fā)生變化,vue會(huì)開啟隊(duì)列緩存,然后在瀏覽器的下一個(gè)tick會(huì)開始Vue 刷新隊(duì)列
并執(zhí)行實(shí)際 (已去重的) 工作。
3.那么react提到的異步渲染也是指在下一個(gè)tick實(shí)現(xiàn)實(shí)際的更新dom的操作嗎?

回答
編輯回答
故林

react里有updateQuque和事務(wù)機(jī)的概念,你可以了解下。因?yàn)閞eact本身的容錯(cuò)機(jī)制做得很好,如果你做了setState后進(jìn)入生命周期時(shí)又觸發(fā)setState的操作,react不會(huì)報(bào)錯(cuò),反而會(huì)推進(jìn)下一個(gè)batchUpdate中,并標(biāo)記一系列dirtyComp,在后續(xù)的事物周期再次處理

2017年9月14日 10:12
編輯回答
獨(dú)特范

給你貼preact源碼

function setState(state, callback) {
    let s = this.state;
    if (!this.prevState) this.prevState = extend({}, s);
    extend(s, typeof state==='function' ? state(s, this.props) : state);
    if (callback) this._renderCallbacks.push(callback);
    enqueueRender(this);
}
function enqueueRender(component) {
    if (!component._dirty && (component._dirty = true) && items.push(component)==1) {
        (options.debounceRendering || defer)(rerender); // 異步呀
    }
}

2017年10月25日 09:55
編輯回答
初念

題主看這篇文章:

https://zhuanlan.zhihu.com/p/...

同道中人。

之前知道setState是異步,但不知道其內(nèi)部機(jī)制以及render觸發(fā)的時(shí)機(jī)。以此去閱讀源碼,可惜我還沒能摸清細(xì)節(jié)就迎來了Fiber更新,閱讀難度驟然上升,直至今天仍沒全部搞懂,但是對(duì)大體的機(jī)制有一些自己的了解,這里拋磚引玉,談?wù)剛€(gè)人看法,同時(shí)希望能有更了解內(nèi)部機(jī)制的大神來談?wù)?,比如司徒正美?/p>

=======================================================

首先明確“異步”指的是“并非每次setState都會(huì)觸發(fā)re-render”。實(shí)際上樓上的回答已經(jīng)涉及到了實(shí)現(xiàn)原理,即setState本質(zhì)上是更新一個(gè)隊(duì)列,然后在后續(xù)邏輯中根據(jù)隊(duì)列內(nèi)容計(jì)算state,觸發(fā)更新。

class組件的更新過程為例,可以大致看出具體的實(shí)現(xiàn)。完整代碼點(diǎn)擊鏈接查看,這里摘取部分代碼分析:

clipboard.png

clipboard.png

上述代碼是componentWillReceiveProps執(zhí)行的過程,這里先不管setState方法的實(shí)現(xiàn)。可以看cwr僅僅是被執(zhí)行了,沒有跟渲染或者狀態(tài)相關(guān)的代碼。

clipboard.png

這是狀態(tài)計(jì)算的代碼,是與生命周期分離的。updateClassInstance最終返回是否需要更新的結(jié)果,接下來的代碼在這里

clipboard.png

clipboard.png

re-render是在這里進(jìn)行的。所以看出setState和render完全是分離的。只有在該走的生命周期結(jié)束后才會(huì)統(tǒng)一render。

這里還沒有介紹setState的內(nèi)部實(shí)現(xiàn),你可以自己去看一下,fiber調(diào)度部分可以跳過,大概能看出是在更新隊(duì)列。(我要去跑步?jīng)]時(shí)間寫了)

2017年12月30日 09:41