React組件的生命周期(16.3以前)和setState API小結(jié)

最近看了程墨的幾篇文章榕栏,對setState這個API有了更加深入的認(rèn)識计螺,下面總結(jié)一下。
先回顧一下React組件的生命周期冶忱。

一尾菇、組件的生命周期

組件生命周期

在掛載期首先會調(diào)用componentWillMount(),然后會接著觸發(fā)render()渲染到頁面囚枪,最后調(diào)用componentDidMount(),在卸載前會調(diào)用componentWillUnmont()派诬,然后卸載組件。
在組件更期時(此處指以props改變?yōu)槔?链沼,首先會從父組件傳來props默赂,觸發(fā)鉤子函數(shù)(hook)componentWillReceiveProps()(若是state改變不會觸發(fā)),然后觸發(fā)shouldComponentUpdate(),如果shouldComponentUpdate()函數(shù)返回false,這時候更新過程就被中斷了括勺,render函數(shù)也不會被調(diào)用了缆八,這時候React不會放棄掉對this.state的更新的,所以雖然不調(diào)用render疾捍,依然會更新this.state耀里。若返回的是true,就會緊接著觸發(fā)componentWillUpdate(),接著觸發(fā)render()拾氓,更新組件的渲染冯挎,最后觸發(fā)觸發(fā)componentDidUpdate(),組件卸載和上述流程一樣咙鞍。

二房官、setState()介紹

引用網(wǎng)上的說法:

React抽象來說,就是一個公式
[圖片上傳失敗...(image-cfb7ee-1531880117865)]

setState是React用來更新state的一個API续滋,用得越多翰守,發(fā)現(xiàn)setState()有很多讓人入坑的地方:

  1. 使用setState()一般情況下(后面會介紹特殊情況)不會立即更新state的值;
  2. setState通過引發(fā)一次組件的更新過程來引發(fā)重新繪制疲酌;
  3. 多次setState函數(shù)調(diào)用產(chǎn)生的效果會合并蜡峰。

對于第一點了袁,引用網(wǎng)上的例子:

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

上面的函數(shù)運行時,似乎對state.count的值加了3次湿颅,但實際上只加了一次载绿,原因正是setState不會立即改變state的值所以后面兩次的this.state其實還是最初的state。

第二點需要提到上面的組件更新期的聲明周期油航,setState調(diào)用引起的React的更新生命周期函數(shù)4個函數(shù):

  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()

當(dāng)shouldComponentUpdate函數(shù)被調(diào)用的時候崭庸,this.state沒有得到更新。
當(dāng)componentWillUpdate函數(shù)被調(diào)用的時候谊囚,this.state依然沒有得到更新怕享。

直到render函數(shù)被調(diào)用的時候,this.state才得到更新。

(或者,當(dāng)shouldComponentUpdate函數(shù)返回false贝润,這時候更新過程就被中斷了,render函數(shù)也不會被調(diào)用了跌帐,這時候React不會放棄掉對this.state的更新的,所以雖然不調(diào)用render芳来,依然會更新this.state含末。)
所以setState一般不會立即更新state的值猜拾,知道render()函數(shù)觸發(fā)即舌。

對于第三點可以簡單理解為:
連續(xù)調(diào)用了兩次this.setState,但是只會引發(fā)一次更新生命周期挎袜,不是兩次顽聂,因為React會將多個this.setState產(chǎn)生的修改放在一個隊列里,緩一緩盯仪,攢在一起紊搪,覺得差不多了再引發(fā)一次更新過程。這樣做的好處是全景,不用每次setState就去觸發(fā)一次render()耀石,這樣太消耗性能。

另外setState()可以接受一個函數(shù)作為參數(shù)爸黄,也就是說可以在里面參入回調(diào)函數(shù):

function increment(state, props) {
  return {count: state.count + 1};
}

function incrementMultiple() {
  this.setState(increment);
  this.setState(increment);
  this.setState(increment);
}

值得注意的是:同樣是把狀態(tài)中的count加1滞伟,但是函數(shù)increment的狀態(tài)的來源不是this.state,而是輸入?yún)?shù)state炕贵,所以加1是累加上去的梆奈。
值得一提的是,在increment函數(shù)被調(diào)用時称开,this.state并沒有被改變亩钟,依然乓梨,要等到render函數(shù)被重新執(zhí)行時(或者shouldComponentUpdate函數(shù)返回false之后)才被改變。這也就是說如果清酥, this.setState(increment)中插入 this.setState({count: this.state.count + 1})會讓前面的努力白費扶镀。如下:

 function incrementMultiple() {
  this.setState(increment);
  this.setState(increment);
  this.setState({count: this.state.count + 1});
  this.setState(increment);
}

在幾個函數(shù)式setState調(diào)用中插入一個傳統(tǒng)式setState調(diào)用(嗯,我們姑且這么稱呼以前的setState使用方式)总处,最后得到的結(jié)果是讓this.state.count增加了2狈惫,而不是增加4,所以不宜混用兩種發(fā)法鹦马。

更詳細(xì)請點擊原文參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胧谈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子荸频,更是在濱河造成了極大的恐慌菱肖,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旭从,死亡現(xiàn)場離奇詭異稳强,居然都是意外死亡,警方通過查閱死者的電腦和手機和悦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門退疫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鸽素,你說我怎么就攤上這事褒繁。” “怎么了馍忽?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵棒坏,是天一觀的道長。 經(jīng)常有香客問我遭笋,道長坝冕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任瓦呼,我火速辦了婚禮喂窟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘央串。我一直安慰自己磨澡,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布蹋辅。 她就那樣靜靜地躺著钱贯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侦另。 梳的紋絲不亂的頭發(fā)上秩命,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天尉共,我揣著相機與錄音,去河邊找鬼弃锐。 笑死袄友,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的霹菊。 我是一名探鬼主播剧蚣,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼旋廷!你這毒婦竟也來了鸠按?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤饶碘,失蹤者是張志新(化名)和其女友劉穎目尖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扎运,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡瑟曲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了豪治。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洞拨。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖负拟,靈堂內(nèi)的尸體忽然破棺而出烦衣,到底是詐尸還是另有隱情,我是刑警寧澤齿椅,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布琉挖,位于F島的核電站启泣,受9級特大地震影響涣脚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寥茫,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一遣蚀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纱耻,春花似錦芭梯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蘑志,卻和暖如春累奈,著一層夾襖步出監(jiān)牢的瞬間贬派,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工澎媒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搞乏,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓戒努,卻偏偏與公主長得像请敦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子储玫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容