精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入淺出 SetState 原理篇

開發(fā) 前端
我知道 setState 被設(shè)計成“異步”是為了性能,但是涉及到源碼解讀我就歇菜了;我知道如何讓它同步,但是遇到真實的代碼情況時,卻不知道如何下手。

前言

想起自己(2021年) 8 月份面試時,被面試官們問了好幾個 setState 的問題,現(xiàn)在想想,雖然回答上問題,但是了解得不深刻。我知道 setState 被設(shè)計成“異步”是為了性能,但是涉及到源碼解讀我就歇菜了;我知道如何讓它同步,但是遇到真實的代碼情況時,卻不知道如何下手。說到底,當時是準備了面經(jīng)把這些概念記下來,而沒有真正理解它

在認識 setState 前,我們問幾個常見問題

  • setState 是同步還是異步?
  • 如果是異步,怎么讓它同步?
  • 為什么要這樣設(shè)計?

基本概念和使用

React 的理念之一是 UI=f(data),修改 data 即驅(qū)動 UI 變化,那么怎么修改呢?React 提供了一個 API ——setState(類組件的修改方法)

官網(wǎng)介紹:

  • setState() 將對組件 state 的更新排入隊列,并通知 React 需要使用更新后的 state 重新渲染此組件及其子組件。這是用于更新用戶界面以響應(yīng)事件處理器和處理服務(wù)器數(shù)據(jù)的主要方式
  • 為了更好的感知性能,React 會延遲調(diào)用它,然后通過一次傳遞更新多個組件。React 并不會保證 state 的變更會立即生效
  • setState() 并不總是立即更新組件。它會批量推遲更新。這使得在調(diào)用 setState() 后立即讀取 this.state 成為了隱患。為了消除隱患,請使用 componentDidUpdate 或者 setState 的回調(diào)函數(shù)(setState(updater, callback)),這兩種方式都可以保證在應(yīng)用更新后觸發(fā)
  • 除非 shouldComponentUpdate() 返回 false,否則 setState() 將始終執(zhí)行重新渲染操作。如果可變對象被使用,且無法在 shouldComponentUpdate() 中實現(xiàn)條件渲染,那么僅在新舊狀態(tài)不一致調(diào)用 setState()可以避免不必要的重新渲染

使用方法

setState(updater, [callback])


參數(shù)一為帶有形式參數(shù)的 updater 函數(shù):

(state, props) => stateChange

// 例如
// this.setState((state, props) => {
// return {counter: state.counter + props.step};
// });


setState 的第一個參數(shù)除了接受函數(shù)外,還可以接受對象類型:

setState(stateChange[, callback])
// 例如:this.setState({count: 2})


setState 的第二個參數(shù)為可選的回調(diào)函數(shù),它將在 setState 完成合并重新渲染組件后執(zhí)行。通常,我們建議使用 componentDidUpdate 來代替此方法

setState(stateChange[, callback])
// 例如: this.setState({count: 2}, () => {console.log(this.state.count)})


與 setState 回調(diào)相比,使用 componentDidUpdate 有什么優(yōu)勢?

stackoverflow 有人問過,也有人回答過:

  • 一致的邏輯
  • 批量更新
  • 什么時候 setState 會比較好? 當外部代碼需要等待狀態(tài)更新時,如 Promise

setState 的特性——批處理

如果在同一周期內(nèi)對多個 setState 進行處理,例如,在同一周期內(nèi)多次設(shè)置商品數(shù)據(jù),相當于:

this.setState({count: state.count + 1});
this.setState({count: state.count + 1});
this.setState({count: state.count + 1});
// ===
Object.assign(
count,
{quantity: state.quantity + 1},
{quantity: state.quantity + 1},
...
)


后調(diào)的 setState 將覆蓋同一周期內(nèi)先調(diào)用 setState 的值

  • setState(stateChange[, callback])
  • setState((state, props) => stateChange[, callback])

setState 必引發(fā)更新過程,但不一定會引發(fā) render 被執(zhí)行,因為 shouldCompomentUpdate 可以返回 false

批處理引發(fā)的問題

問題1:連續(xù)使用 setState,為什么不能實時改變

state.count = 0;
this.setState({count: state.count + 1});
this.setState({count: state.count + 1});
this.setState({count: state.count + 1});
// state.count === 1,不是 3


因為 this.setState 方法為會進行批處理,后調(diào)的 setState 會覆蓋統(tǒng)一周期內(nèi)先調(diào)用的 setState 的值,如下圖所示:

state.count = 0;
this.setState({count: state.count + 2});
this.setState({count: state.count + 3});
this.setState({count: state.count + 4});
// state.count === 4


問題2:為什么要 setState,而不是直接 this.state.xx = oo?

因為 setState 做的事情不僅僅只是修改了 this.state 的值,另外最重要的是它會觸發(fā) React 的更新機制,會進行diff,然后將 patch 部分更新到真實 dom 里

如果你直接 this.state.xx = oo 的話,state 的值確實會改,但是它不會驅(qū)動 React 重渲染。setState 能幫助我們更新視圖,引發(fā) shouldComponentUpdate、render 等一系列函數(shù)的調(diào)用。至于批處理,React 會將 setState 的效果放入隊列中,在事件結(jié)束之后產(chǎn)生一次重新渲染,為的就是把 Virtual DOM 和 DOM 樹操作降到最小,用于提高性能

當調(diào)用 setState 后,React 的 生命周期函數(shù) 會依次順序執(zhí)行

  • static getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate

問題3:那為什么會出現(xiàn)異步的情況呢?(為什么這么設(shè)計?)

因為性能優(yōu)化。假如每次 setState 都要更新數(shù)據(jù),更新過程就要走五個生命周期,走完一輪生命周期再拿 render 函數(shù)的結(jié)果去做 diff 對比和更新真實 DOM,會很耗時間。所以將每次調(diào)用都放一起做一次性處理,能降低對 DOM 的操作,提高應(yīng)用性能

問題4:那如何在表現(xiàn)出異步的函數(shù)里可以準確拿到更新后的 state 呢?

通過第二個參數(shù) setState(partialState, callback) 中的 callback 拿到更新后的結(jié)果

onHandleClick() {
this.setState(
{
count: this.state.count + 1,
},
() => {
console.log("點擊之后的回調(diào)", this.state.count); // 最新值
}
);
}


或者可以直接給 state 傳遞函數(shù)來表現(xiàn)出同步的情況

this.setState(state => {
console.log("函數(shù)模式", state.count);
return { count: state.count + 1 };
});


執(zhí)行原理

首先先了解三種渲染模式

  • legacy 模式:ReactDOM.render(, rootNode) 。這是當前 React app 使用的方式。當前沒有計劃刪除本模式,但是這個模式可能不支持新功能
  • blocking 模式:
  • ReactDOM.createBlockingRoot(rootNode).render() 。目前正在實驗中,作為遷移到 concurrent 模式的第一個步驟
  • concurrent 模式 :ReactDOM.createRoot(rootNode).render()。目前在實驗中,未來穩(wěn)定之后,打算作為 React 的模式開發(fā)模式。這個模式開啟了所有的新功能 擁有不同的優(yōu)先級,更新的過程可以被打斷

在 legacy 模式下,在 React 的 setState 函數(shù)實現(xiàn)中,會根據(jù)一個變量 isBatchingUpdates 判斷是直接更新 this.state 還是放到隊列中回頭再說,而 isBatchingUpdates 默認是 false,也就表示 setState 會同步更新 this.state,但是,有一個函數(shù) batchedUpdates,這個函數(shù)會把 isBatchingUpdates 修改為 true,而當 React 在調(diào)用事件處理函數(shù)之前就會調(diào)用這個 batchedUpdates,造成的后果,就是由 React 控制的事件處理過程 setState 不會同步更新 this.state

像 addEventListener 綁定的原生事件、setTimeout/setInterval 會走同步,除此之外,也就是 React 控制的事件處理 setState 會異步

而 concurrent 模式都是異步,這也是未來 React 18 的默認模式

總結(jié)

首先,我們總結(jié)下關(guān)鍵知識點

  • setState 不會立即改變 React 組件中 state 的值
  • setState 通過引發(fā)一次組件的更新過程來引發(fā)重新繪制
  • 多次 setState 函數(shù)調(diào)用產(chǎn)生的效果會合并(批處理)

其次,回答一下文章開頭的問題(第二第三問題在文中已經(jīng)回答)

setState 是同步還是異步?

  • 代碼同步,渲染看模式 legacy模式,非原生事件、setTimeout/setInterval 的情況下為異步;addEventListener 。 綁定原生事件、setTimeout/setInterval 時會同步concurrent 模式:異步

責任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2021-07-20 15:20:02

FlatBuffers阿里云Java

2018-12-25 08:00:00

2021-03-16 08:54:35

AQSAbstractQueJava

2011-07-04 10:39:57

Web

2021-08-10 14:10:02

Nodejs后端開發(fā)

2020-11-06 09:24:09

node

2017-07-02 18:04:53

塊加密算法AES算法

2019-01-07 15:29:07

HadoopYarn架構(gòu)調(diào)度器

2012-05-21 10:06:26

FrameworkCocoa

2012-11-30 15:37:10

2022-09-26 09:01:15

語言數(shù)據(jù)JavaScript

2012-05-31 10:57:06

HTML5

2012-05-30 10:52:09

HTML5

2012-05-30 14:51:09

HTML5

2012-05-30 13:17:46

HTML5

2012-05-30 13:49:52

HTML5

2012-05-30 11:11:42

HTML5

2012-05-30 13:26:12

HTML5

2012-05-31 09:19:22

HTML5

2012-05-31 09:54:13

HTML5
點贊
收藏

51CTO技術(shù)棧公眾號

欧美老女人另类| 色噜噜狠狠狠综合欧洲色8| 日韩av电影免费观看高清完整版| 最新91在线视频| 日韩欧美中文视频| 17videosex性欧美| 国产精品私房写真福利视频| 99久久精品免费看国产四区| 少妇高潮av久久久久久| 亚洲欧美综合久久久| 亚洲精品久久久久久久久久久| 天天干在线影院| 久久av色综合| 国产精品国产三级国产aⅴ原创 | 久久黄色片视频| 国产黄色片在线播放| 国产成人h网站| 国产精品男人的天堂| 日韩精品一区三区| 亚洲精品成人| 中文字幕欧美专区| 麻豆国产精品一区| 日韩在线观看一区二区三区| 欧美性xxxxxxxx| 春日野结衣av| 高清电影在线观看免费| 中文字幕日韩精品一区| 日韩一区二区三区资源| 亚洲欧美丝袜中文综合| 国产98色在线|日韩| 国产欧美精品日韩精品| 波多野结衣视频观看| 国产日韩欧美一区在线 | 亚洲二区中文字幕| 97超碰人人看| www.久久热| 欧美美女一区二区在线观看| 青青在线视频免费| 91精品产国品一二三产区| 午夜视频在线观看一区二区| 青青在线视频免费观看| 国产黄色在线观看| 亚洲精品中文字幕在线观看| 永久域名在线精品| 欧洲不卡视频| 椎名由奈av一区二区三区| 夜夜爽www精品| 日本高清中文字幕在线| 国产精品蜜臀av| 亚洲欧美日本国产有色| av网站大全在线观看| 国产欧美一区二区精品性| 日韩在线三区| 亚洲xxxxxx| 亚洲欧洲色图综合| 看全色黄大色大片| 在线观看男女av免费网址| 亚洲猫色日本管| 日韩精品久久一区二区| 激情av在线播放| 欧美日韩在线视频一区二区| 免费在线观看日韩视频| 九九热线视频只有这里最精品| 色激情天天射综合网| 五月婷婷狠狠操| 欧美亚洲黄色| 欧美一卡二卡在线| a级片在线观看视频| 色爱综合av| 在线视频欧美性高潮| 欧美日韩黄色网| 亚洲私拍自拍| 国产精品69av| 国产又粗又猛又爽又黄的视频一| 国产真实乱对白精彩久久| 96成人在线视频| 日韩二区三区| 亚洲天堂久久久久久久| 国产成人艳妇aa视频在线| 国产中文在线播放| 欧美日精品一区视频| 尤物网站在线看| 色老板在线视频一区二区| 国产一区二区三区视频| 婷婷在线精品视频| 久久婷婷丁香| 91久久精品国产91久久| 午夜av免费观看| 中文字幕制服丝袜一区二区三区 | 日韩国产高清在线| 亚洲影院色无极综合| 天天干天天舔天天射| 国产精品污网站| www.av91| 成人精品国产亚洲| 亚洲成色999久久网站| 亚洲精品日日夜夜| 天堂一区二区三区| 国产一线二线在线观看| 在线精品亚洲一区二区不卡| 无码人妻一区二区三区免费n鬼沢| 亚洲精品无吗| 九色91av视频| 亚洲在线免费观看视频| 91小视频在线观看| 高清无码一区二区在线观看吞精| 深夜成人福利| 亚洲国产美女久久久久| 搜索黄色一级片| 免费在线欧美黄色| 粉嫩高清一区二区三区精品视频 | 免费91麻豆精品国产自产在线观看| 日韩乱码在线观看| 国产精品主播直播| 亚洲欧洲精品在线观看| 欧美日韩大片| 亚洲国产精品va在线看黑人| 午夜激情福利网| 日本午夜精品视频在线观看| 极品校花啪啪激情久久| 久久亚洲资源| 欧美一级淫片007| 成人免费视频入口| 日欧美一区二区| 蜜桃欧美视频| 亚洲妇女成熟| 亚洲国产一区二区三区在线观看| 久草国产在线视频| 国产在线观看一区二区| 在线观看国产一区| 日本一区二区三区中文字幕| 亚洲人高潮女人毛茸茸| 日韩中文字幕在线观看视频| 99国产精品久久久久| 久久久久久久久久网| 国产成人一二| 久久久久久久久久久人体| 不卡av中文字幕| 亚洲精品成人在线| 美女被爆操网站| 欧美日韩综合| 激情小说综合网| 色在线视频观看| 亚洲老头同性xxxxx| 人人干人人干人人干| www.欧美日韩| 99视频在线免费播放| 天天躁日日躁成人字幕aⅴ| 97成人在线视频| 免费在线黄色电影| 在线视频国产一区| 久草福利资源在线| 国产一区不卡视频| 国产av熟女一区二区三区| 影音先锋欧美激情| 97精品国产97久久久久久春色| 污视频在线免费观看| 欧美午夜激情小视频| 六月婷婷七月丁香| 美女mm1313爽爽久久久蜜臀| 在线精品亚洲一区二区| 欧美激情三级| 午夜免费久久久久| 国产爆初菊在线观看免费视频网站| 欧美中文字幕久久| 在线免费观看亚洲视频| 国产91露脸合集magnet| 国产亚洲欧美在线视频| 精品视频免费| 亚洲精品欧美极品| caoporn视频在线| 亚洲午夜女主播在线直播| 伊人网av在线| 亚洲国产裸拍裸体视频在线观看乱了 | 亚洲电影免费观看高清| 无码人妻av免费一区二区三区| 国产精品久久久久久久久免费相片| 91亚洲一区二区| 美女国产一区| 青青草综合视频| 一区二区三区四区在线看| 成人免费福利视频| 亚洲淫成人影院| www国产精品视频| 色呦呦免费观看| 欧美日韩国产电影| 奇米影视第四色777| 国产精品乱人伦| 李丽珍裸体午夜理伦片| 蜜桃传媒麻豆第一区在线观看| 久久久天堂国产精品| 亚洲精品推荐| 福利精品视频| 韩国理伦片久久电影网| 性欧美长视频免费观看不卡| 在线国产情侣| 亚洲老头老太hd| 乱色精品无码一区二区国产盗| 欧美性猛片aaaaaaa做受| 久久精品这里只有精品| 日本一区二区成人在线| 在线免费看黄色片| 精品一区二区免费| 99精品视频播放| 国自产拍偷拍福利精品免费一| 亚洲开发第一视频在线播放| 玖玖玖免费嫩草在线影院一区| 国产欧美日韩最新| 亚洲成人激情社区| 26uuu亚洲伊人春色| 欧美bbbxxxxx| 美女啪啪无遮挡免费久久网站| 国产福利在线视频| 日韩av在线播放资源| 性生活三级视频| 5月丁香婷婷综合| 黄色片视频免费| 天天av天天翘天天综合网色鬼国产| 翔田千里88av中文字幕| 国产精品久久久一本精品| 国产 欧美 在线| 久久老女人爱爱| 国产精品300页| 成人黄页在线观看| 激情av中文字幕| 国产aⅴ精品一区二区三区色成熟| 一区二区免费av| 久久99久久久久久久久久久| 天堂在线资源视频| 男人的j进女人的j一区| 18岁视频在线观看| 亚洲永久免费精品| 久在线观看视频| 国产精品三上| 动漫av网站免费观看| 国产精品久久久久久久久久妞妞| 999一区二区三区| 亚洲视频免费| 欧美久久久久久久久久久久久| 亚洲国产99| 国产毛片视频网站| 亚洲尤物精选| 亚洲综合在线网站| 日本特黄久久久高潮| 免费一区二区三区在线观看| 久久99精品久久久久久动态图 | 91丝袜美腿高跟国产极品老师 | 性久久久久久久久| 国产精品a成v人在线播放| 亚洲va国产va欧美va观看| 日本学生初尝黑人巨免费视频| 亚洲va欧美va人人爽午夜| 91在线看视频| 色欲综合视频天天天| 五月激情丁香网| 欧美精品乱码久久久久久按摩| 国产女人爽到高潮a毛片| 欧美一级艳片视频免费观看| 亚洲av无码乱码国产麻豆| 亚洲成在人线av| 欧美美女色图| 日韩在线观看免费av| 亚洲制服国产| 91高潮在线观看| 欧亚一区二区| 亚洲一区二区三区四区视频| 91精品导航| 欧美一区二区视频17c| 成人黄色av| 日韩专区第三页| 国产亚洲高清视频| 男人搞女人网站| 国产suv精品一区二区三区| 黄色污在线观看| 中文字幕第一区| 国产亚洲欧美精品久久久久久| 欧美日韩免费看| 97成人在线观看| 亚洲经典中文字幕| av影片免费在线观看| 欧美激情网友自拍| 成人在线网站| 国产精品毛片一区视频| 狠狠综合久久av一区二区蜜桃| 9999在线观看| 国产精品久久久久久久免费软件| 狠狠干狠狠操视频| 99久久免费精品高清特色大片| 美国美女黄色片| 亚洲国产欧美在线| 中文字幕男人天堂| 亚洲精品99久久久久| 成人黄色网址| 日韩美女在线观看| 东京久久高清| 中文字幕一区二区三区四区五区 | 一级黄色高清视频| 久久综合久久综合亚洲| 九九在线观看视频| 欧美日韩一区高清| 香蕉久久国产av一区二区| 久久在线观看视频| 香蕉久久免费电影| 国产亚洲精品自在久久| 国产精品91一区二区三区| 无码人妻精品一区二区三区在线| 国产一区不卡精品| 一级二级黄色片| 色综合天天狠狠| 好吊视频一二三区| 久久精品青青大伊人av| 免费成人直播| 精品91免费| 在线成人av| 国产在线视频三区| 国产精品国产三级国产普通话蜜臀| 中文字幕av影院| 亚洲精品ady| h片精品在线观看| 91福利入口| 围产精品久久久久久久| 亚洲无吗一区二区三区| 2020日本不卡一区二区视频| 国产在线视频你懂的| 欧美一区二区三区在线观看 | 精品日韩毛片| 成人在线观看黄| www成人在线观看| 在线观看亚洲欧美| 亚洲精品电影网| av中文资源在线资源免费观看| 成人蜜桃视频| 在线观看视频免费一区二区三区| 奇米777在线| 亚洲综合视频在线| 午夜免费福利视频| 久久91精品国产91久久久| 在线观看视频一区二区三区| 日本大胆人体视频| 国产a精品视频| 国产一级久久久| 亚洲精品在线观看网站| 91探花在线观看| 蜜桃传媒视频麻豆一区 | 大伊人狠狠躁夜夜躁av一区| 天堂网在线资源| 日本高清久久天堂| 国产亚洲欧美日韩在线观看一区二区 | 精品少妇一区二区三区密爱| 欧美日韩色一区| 黄色小网站在线观看| 亚洲伊人成综合成人网| 欧美日韩一区二区三区四区在线观看| 在线播放av网址| 精品女同一区二区三区在线播放| 四虎精品在永久在线观看 | 久久亚洲精品一区二区| 高清不卡一区| 69sex久久精品国产麻豆| 99久久精品免费看| 69视频免费看| 久久精品国产精品亚洲| 亚洲不卡视频| 国产精品沙发午睡系列| 国产欧美日韩久久| av资源免费看| 97在线视频精品| 精品欧美久久| 性生交大片免费看l| 欧美日韩国产在线看| av午夜在线| 成人资源av| 久久久久在线| 亚洲欧美一区二区三区四区五区| 亚洲第一精品夜夜躁人人爽| 欧美日韩亚洲国产| 黄色录像特级片| 久久夜色精品国产欧美乱极品| 亚洲天堂视频网| 高清在线视频日韩欧美| 不卡中文字幕| 国产69视频在线观看| 在线观看亚洲一区| 色帝国亚洲欧美在线| 日韩aⅴ视频一区二区三区| 国产精品中文字幕一区二区三区| 永久免费无码av网站在线观看| 日韩中文字幕在线视频播放| 国产伦精品一区二区三区在线播放 | 午夜欧美激情| 日本丰满少妇黄大片在线观看| 972aa.com艺术欧美| 国产普通话bbwbbwbbw| 57pao精品| 国语精品一区| 91久久国产综合| 国产午夜精品一区理论片飘花| 日韩一二三区| 91女神在线观看| 日韩欧美成人免费视频|