亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

React-setState雜記

yuxue / 3253人閱讀

摘要:簡(jiǎn)單的舉下例子如等生命周期以及的事件即為異步更新,這里不顯示具體代碼。因?yàn)橹挥挟?dāng)父組件后才傳給子組件,那么如果要變成同步的,就需要放棄。

前言

在看React的官方文檔的時(shí)候, 發(fā)現(xiàn)了這么一句話,State Updates May Be Asynchronous,于是查詢了一波資料, 最后歸納成以下3個(gè)問(wèn)題

setState為什么要異步更新,它是怎么做的?

setState什么時(shí)候會(huì)異步更新, 什么時(shí)候會(huì)同步更新?

既然setState需要異步更新, 為什么不讓用戶可以同步讀到state的新值,但更新仍然是異步?

常見(jiàn)場(chǎng)景下的異步更新

以下是官方文檔的一個(gè)例子, 調(diào)用了3次incrementCount方法, 期望this.state.count的值是3, 但最后卻是1

incrementCount() {
  this.setState({count: this.state.count + 1});
}

handleSomething() {
  // Let"s say `this.state.count` starts at 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // When React re-renders the component, `this.state.count` will be 1, but you expected 3.

  // This is because `incrementCount()` function above reads from `this.state.count`,
  // but React doesn"t update `this.state.count` until the component is re-rendered.
  // So `incrementCount()` ends up reading `this.state.count` as 0 every time, and sets it to 1.

  // The fix is described below!
}

那么就可以引出第一個(gè)問(wèn)題

setState為什么要異步更新,它是怎么做的?

深入源碼你會(huì)發(fā)現(xiàn):(引用程墨老師的setState何時(shí)同步更新?tīng)顟B(tài))

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

然后我在網(wǎng)上引用了這張圖(侵刪)

從結(jié)論和圖都可以得出, setState是一個(gè)batching的過(guò)程, React官方認(rèn)為, setState會(huì)導(dǎo)致re-rederning, 而re-rederning的代價(jià)是昂貴的, 所以他們會(huì)盡可能的把多次操作合并成一次提交。以下這段話是Dan在Issue中的回答:

中心意思大概就是:
同步更新setState并re-rendering的話在大部分情況下是無(wú)益的, 采用batching會(huì)有利于性能的提升, 例如當(dāng)我們?cè)跒g覽器插入一個(gè)點(diǎn)擊事件時(shí),父子組件都調(diào)用了setState,在batching的情況下, 我們就不需要re-render兩次孩子組件,并且在退出事件之前re-render一次即可。

那么如果我們想立即讀取state的值, 其實(shí)還有一個(gè)方法, 如下代碼:
因?yàn)楫?dāng)傳入的是一個(gè)函數(shù)時(shí),state讀取的是pending隊(duì)列中state的值

incrementCount() {
  this.setState((state) => {
    // Important: read `state` instead of `this.state` when updating.
    return {count: state.count + 1}
  });
}

handleSomething() {
  // Let"s say `this.state.count` starts at 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();

  // If you read `this.state.count` now, it would still be 0.
  // But when React re-renders the component, it will be 3.
}

當(dāng)然, 仔細(xì)看React文檔的話, 可以發(fā)現(xiàn), State Updates May Be Asynchronou里面有一個(gè)may的字眼,也就是可能是異步更新, 因而引出第二個(gè)問(wèn)題

setState什么時(shí)候會(huì)異步更新, 什么時(shí)候會(huì)同步更新?

其實(shí)從第一個(gè)問(wèn)題中我們就知道,React是根據(jù)isBatchingUpdates來(lái)合并更新的, 那么當(dāng)調(diào)用setState的方法或者函數(shù)不是由React控制的話, setState自然就是同步更新了。

簡(jiǎn)單的舉下例子:

如componentDidMount等生命周期以及React的事件即為異步更新,這里不顯示具體代碼。

如自定義的瀏覽器事件,setTimeout,setInterval等脫離React控制的方法, 即為同步更新, 如下(引用程墨老師的setState何時(shí)同步更新?tīng)顟B(tài))

componentDidMount() {
  document.querySelector("#btn-raw").addEventListener("click", this.onClick);
}
onClick() {
  this.setState({count: this.state.count + 1});
  console.log("# this.state", this.state);
}
// ......
render() {
  console.log("#enter render");
  return (
    
{this.state.count}
) }

有的人也會(huì)想能不能React依然合并更新, 但用戶可以同步讀取this.state的值, 這個(gè)問(wèn)題在React的一個(gè)Issue上有提到, 也是我們的第三個(gè)問(wèn)題

既然setState需要異步更新, 為什么不讓用戶可以同步讀到state的新值,但更新仍然是異步?

這個(gè)問(wèn)題可以直接在Dan的回答中得到:

This is because, in the model you proposed, this.state would be flushed immediately but this.props wouldn’t. 
And we can’t immediately flush this.props without re-rendering the parent, which means we would have to give up on batching (which, depending on the case, can degrade the performance very significantly).

大概意思就是說(shuō):

如果在應(yīng)用中,this.state的值是同步,但是this.props卻不是同步的。因?yàn)閜rops只有當(dāng)re-rendering父組件后才傳給子組件,那么如果要props變成同步的, 就需要放棄batching。 但是batching不能放棄。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/101595.html

相關(guān)文章

  • 2018.12月問(wèn)題整理雜記

    摘要:布局如下對(duì)于這塊,我不是很理解,后發(fā)現(xiàn),注銷這個(gè)樣式,用可以解決。后查閱一些資料,到了原因。 -12.24-:html布局如下: html css javascript vue css: tab{ width: 600px; margin: 0 auto; } .tab-tit{ width: 600px; font-si...

    wudengzan 評(píng)論0 收藏0
  • React-Router 雜記

    摘要:三種的區(qū)別即對(duì)應(yīng)中的值,如,服務(wù)器對(duì)任務(wù)都返回同一個(gè),具體的路徑由瀏覽器區(qū)分,因?yàn)闉g覽器不會(huì)發(fā)送后面的值給服務(wù)器。如果是即變成這樣,,所以要對(duì)服務(wù)器配置不同的返回不同的資源。就是沒(méi)有的情況,比如。 三種Router的區(qū)別 1. HashRouter: 即對(duì)應(yīng)url中的hash值,如xx.com/#/a、xx.com/#/a/b, 服務(wù)器對(duì)任務(wù)url都返回同一個(gè)url,具體的路徑由瀏覽器...

    keelii 評(píng)論0 收藏0
  • React-flux雜記

    摘要:簡(jiǎn)介是一種搭建客戶端的應(yīng)用架構(gòu),更像是一種模式而不是一個(gè)框架。 簡(jiǎn)介 Flux是一種搭建WEB客戶端的應(yīng)用架構(gòu),更像是一種模式而不是一個(gè)框架。 特點(diǎn) 單向數(shù)據(jù)流 showImg(https://segmentfault.com/img/remote/1460000018128072?w=1300&h=708); 與MVC的比較 1.傳統(tǒng)的MVC如下所示(是一個(gè)雙向數(shù)...

    王巖威 評(píng)論0 收藏0
  • JavaScript 雜記(一)

    摘要:基礎(chǔ)簡(jiǎn)單基礎(chǔ)數(shù)據(jù)類型值得注意的是的值是,表示一個(gè)空對(duì)象指針,沒(méi)有指向任何對(duì)象。的值是,表示申明變量或?qū)ο蟮膶傩詤s未初始化。值是派生自的,所以對(duì)他們執(zhí)行相等測(cè)試會(huì)返回。字符串單引號(hào)和雙引號(hào)都可以用來(lái)表示字符串,只要前后一致即可。 目的 記憶總是會(huì)隨著時(shí)間而淡化,學(xué)習(xí)了點(diǎn)什么,就記錄下點(diǎn)什么。 做點(diǎn)什么,總比不做要好。 基礎(chǔ) 簡(jiǎn)單(基礎(chǔ))數(shù)據(jù)類型 Number ...

    raise_yang 評(píng)論0 收藏0
  • 雜記之關(guān)于織夢(mèng)網(wǎng)站修改的一些操作

    摘要:修改菜單首先,修改,為什么看了就明白了提示信息在里修改最后大多數(shù)要修改的內(nèi)容都在里,希望可以幫助到你,沒(méi)涉及的那你就再百度一下吧,學(xué)藝不精歡迎指正 1.修改菜單首先,修改dede/temples/index2.html + dede/inc/inc_menu.php,為什么?!看了就明白了 2.dede提示信息在dede/sys_data_done.php 里修改 最后大多數(shù)要修改的...

    yy13818512006 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<