成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:“寶子,setState 是同步還是異步的呀?”

開發(fā) 前端
在進入主題之前,你肯定需要先學會 React 的基本使用。如果不會,請點贊離開;如果會用 React ,那就點贊收藏后離開(●'?'●)。

[[417888]]

本文轉載自微信公眾號「勾勾的前端世界」,作者西嶺。轉載本文請聯(lián)系勾勾的前端世界公眾號。

這一次,我將帶你一次性搞懂 React 中常見的 setState 原理。

setState 本身的默認行為

在進入主題之前,你肯定需要先學會 React 的基本使用。如果不會,請點贊離開;如果會用 React ,那就點贊收藏后離開(●'?'●)。

我們在使用 React 的時候,經常會用到 state(一句廢話),但是真正能完全搞清楚 setState 的帥哥美女,確實沒幾個。畢竟程序員都不太可能像我一樣博學(和好看)。那么,要搞清楚它,應該去投胎(整容)嗎?

不,你需要先搞清楚 setState 本身的默認行為。

其實也很簡單,我們都知道,setState可以傳遞對象形式的狀態(tài),也可以傳遞函數形式的狀態(tài)。而不論狀態(tài)是對象形式還是函數形式,它都會先將所有狀態(tài)保存起來,然后進行狀態(tài)合并,所有狀態(tài)合并完成后再進行一次性 DOM 更新。

如果狀態(tài)是對象形式,后面的狀態(tài)會直接覆蓋前面的狀態(tài)。類似于 Object.assign() 的合并操作。

對于對象狀態(tài)這一點,我們有請翠花,上代碼:

運行代碼,Dom 中展示的結果為 1。很顯然兩次 setState 只有一次生效了。

真的嗎?其實兩次都有生效,只不過這兩次 setState 在執(zhí)行前,被合并成了一個。你不能說到底是那個生效,你可以說兩個都沒生效,因為最終執(zhí)行的是被合并的那個代碼。

如果狀態(tài)是函數形式,那么依次調用函數進行狀態(tài)累積,所有函數調用完成后, 得到最終狀態(tài),最終進行一次性 DOM 更新。

翠花,再來一段代碼……

明顯不一樣的結果就能說明,兩次都執(zhí)行了,因為函數狀態(tài)并不會合并,而是以此運行。

好了,翠花可以先下去休息了,前置只是我們已經梳理完了,那么,對于 setState 的研究就結束了嗎?當然不是,接下來,讓我們換個場子,繼續(xù)掰滔(battle)。

setState 同步 OR 異步

在面試場景中,只要和 React 相關,面試官一定舔著臉問你:“ 寶子,setState 是同步還是異步的呀 ” 。

面對這樣的無恥刁難,我們需要先明確,從 API 層面上說,它就是普通的調用執(zhí)行的函數,自然是同步 API 。

因此,這里所說的同步和異步指的是 API 調用后更新 DOM 是同步還是異步的。

來,我們有請娜塔莎,上代碼……

果然,洋妹子端上來的代碼確實不好消化,通過結果我們發(fā)現,非常奇怪的一個現象:

第一次事件執(zhí)行顯然為異步的,先打印了兩個 0,Dom 隨之改變?yōu)?1 ;

第二次同樣是異步的,但是我們發(fā)現多次執(zhí)行沒效果 (異步?);

而第三次又是同步執(zhí)行的了;

這什么情況,洋妹子給我們下了迷藥嗎?看我葵花寶典戳破它。

先說結論,首先,同步和異步主要取決于它被調用的環(huán)境。

  • 如果 setState 在 React 能夠控制的范圍被調用,它就是異步的。

比如合成事件處理函數, 生命周期函數, 此時會進行批量更新, 也就是將狀態(tài)合并后再進行 DOM 更新。

  • 如果 setState 在原生 JavaScript 控制的范圍被調用,它就是同步的。

比如原生事件處理函數中, 定時器回調函數中, Ajax 回調函數中, 此時 setState 被調用后會立即更新 DOM 。

為什么會這樣呢?

其實,我們看到的所謂的 “異步”,是開啟了 “批量更新” 模式的。

批量更新模式可以減少真實 DOM 渲染的次數,所以只要是 React 能夠控制的范圍,出于性能因素考慮,一定是批量更新模式。批量更新會先合并狀態(tài),再一次性做 DOM 更新。

那么假設沒有批量更新呢?

從生命周期的角度來看,每一次的 setState 都是一個完整的更新流程,這里面就包含了重新渲染 (re-render) 在內的很多操作,大體的流程如下:

  1. shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate; 

re-render 本身涉及對 DOM 的操作,它會帶來較大的性能開銷。假如說 “一次 setState 就觸發(fā)一個完整的更新流程” 這個結論成立,那么每一次 setState的調用都會觸發(fā)一次 re-render,我們的視圖很可能沒刷新幾次就卡死了,渲染就會出現下面這樣的流程:

因此,setState 異步(或者說是批量更新)的一個重要動機就是避免頻繁的 re-render。

在實際的 React 運行時中,setState 異步的實現方式有點類似于瀏覽器里的 Event-Loop:

每來一個setState,就把它塞進一個隊列里。等時機成熟,再把隊列里的 state 結果做合并,最后只針對最新的 state 值走一次更新流程。

這個過程,叫作“批量更新”,批量更新的過程正如下面代碼中的箭頭流程圖所示:

只要我們的同步代碼還在執(zhí)行,“進隊列” 這個動作就不會停止。因此就算我們在React 中寫了一個 N 次的 setState 循環(huán),也只是會增加 state 任務入隊的次數,并不會帶來頻繁的 re-render。當 N 次調用結束后,僅僅是 state 的任務隊列內容發(fā)生了變化, state 本身并不會立刻改變。

為了更好地讓你吃下娜塔莎,哦不對,是娜塔莎端上來的美食,我?guī)湍闶崂砹?setState 的執(zhí)行流程圖:

 

當然,你可能看不懂這個流程圖(是有多笨啊),沒關系,下面還會有的。

如果為非批量更新模式,調用多少次 setState 就會渲染多少次真實 DOM,性能較低。

但是我們在某些條件下需要對 JS 控制的區(qū)域實現批量更新 ( 異步更新 DOM ) ,那應該怎么做呢?

強制批量更新

其實很簡單,我都不好意思說 so easy ,因為這玩意簡直就是 so TM 的 easy 。

我們只需要將代碼包裹在 unstable_batchedUpdates 方法的回調函數中就可以實現強制批量更新。

具體使用方式也很簡單,從 react-dom 中引入進來,然后將代碼放入調用函數中就可以了。

(翠花和娜塔莎結婚了,我來給大家上代碼)

 

截止到現在,我們成就了一對完美的愛情,啊,呸~

 

責任編輯:武曉燕 來源: 勾勾的前端世界
相關推薦

2022-06-13 06:20:42

setStatereact18

2021-06-29 09:47:34

ReactSetState機制

2023-11-15 09:14:27

Java值傳遞

2021-09-07 10:44:33

Java 注解開發(fā)

2024-10-24 09:22:30

2024-02-04 10:08:34

2021-02-19 10:02:57

HTTPSJava安全

2024-12-25 15:44:15

2024-02-22 15:36:23

Java內存模型線程

2021-12-08 06:53:29

面試動態(tài)代理

2015-08-13 10:29:12

面試面試官

2024-05-11 15:11:44

系統(tǒng)軟件部署

2022-09-29 07:30:57

數據庫索引字段

2022-07-15 08:22:42

對象符串鍵Symbol

2023-02-08 07:04:20

死鎖面試官單元

2025-04-14 11:41:12

RocketMQ長輪詢配置

2020-08-10 07:58:18

異步編程調用

2024-10-15 10:00:06

2021-04-30 20:25:20

Spring MVCJava代碼

2021-03-03 17:26:45

面試Synchronous底層
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 韩日三级 | 中文字幕91av | 成人精品鲁一区一区二区 | www久久爱| 成人国产精品免费观看 | 日韩视频一区 | 紧缚调教一区二区三区视频 | 丁香综合 | 午夜影院在线观看 | 国产精品久久久久无码av | 国产一区二区三区网站 | 国产精品视频不卡 | 日本不卡一区二区三区 | 最新伦理片 | 欧美一区二区 | 精品国产一区探花在线观看 | 精品在线视频播放 | 91国产视频在线 | 成人av播放 | 日韩一区二区三区av | 亚洲国产一区二区在线 | 中文字幕在线播放不卡 | 国产免费福利在线 | 色综合天天天天做夜夜夜夜做 | 黄色网页在线 | 在线播放中文字幕 | 91se在线| 日韩一级免费大片 | 中文一区 | 久久久精品网站 | 不卡的av一区 | 日韩成人在线网站 | 亚洲午夜av久久乱码 | 乱码av午夜噜噜噜噜动漫 | 日本五月婷婷 | 亚洲一区视频在线 | 自拍偷拍一区二区三区 | 国产一区二区三区免费观看在线 | 黄视频免费 | 中文字幕在线视频免费观看 | 羞羞色影院|