React的生命周期

react的一些函數(shù)的官方介紹

函數(shù) / 方法

ES6中React組件是用class來定義的,關(guān)于class的知識可以看阮一峰的es6的相關(guān)介紹, 當(dāng)然描滔,如果你英文不錯也可以看React的官方介紹

// 定義一個TodoList的React組件,通過繼承React.Component來實現(xiàn)
class TodoList extends React.Component {
  ...
}

class的定義方法

constructor(props, context) {
  super(props);
  this.state = {};
}

class中的構(gòu)造器,主要功能是初始化一些變量(state等)并繼承父類(父組件)的屬性止后,需要注意的是React組件中如果有定義constructor函數(shù)就必須要寫super(),而constructor里面如果要使用this.props的話就要super(props)溜腐,但是就算不寫也不影響其他函數(shù)使用props因為React會自動傳入译株。

render() {
  return (
    <div />
  );
}

渲染頁面,由于setState會觸發(fā)render挺益,所以不要在這里面setState古戴。

void componentWillMount() // unsafe, 16.4廢棄,constructor的執(zhí)行過程與之相似

在組件掛載之前調(diào)用一次矩肩。

void componentDidMount()

在組件掛載之后調(diào)用一次现恼。

void componentWillReceiveProps(nextProps) // unsafe, 16.4廢棄

父組件發(fā)生更新時被調(diào)用(不管props有沒有更新,也不管父子組件之間有沒有數(shù)據(jù)交換)

bool shouldComponentUpdate(nextProps, nextState)

判斷是否要調(diào)用render黍檩,默認(rèn)返回true叉袍,每次setState/componentWillReceiveProps觸發(fā)后調(diào)用,在比較復(fù)雜的應(yīng)用里刽酱,有一些數(shù)據(jù)的改變并不影響界面展示喳逛,可以在這里做判斷,優(yōu)化渲染效率棵里。

void componentWillUpdate(nextProps, nextState) // unsafe 16.4廢棄润文,可以用getDerivedStateFromProps替代

組件將要更新之前調(diào)用,

static  getDerivedStateFromProps(props, state) // 16.3++版本

組件更新(render)之前調(diào)用殿怜,第一次初始化和無論何種方式更新組件都會調(diào)用此方法典蝌, 要注意的是 要加static

getSnapshotBeforeUpdate() // 16.3++版本

頁面之前的dom元素還沒改變之前調(diào)用,具體周期是render之后componentDidUpdate之前头谜,返回的值可以被componentDidUpdate接收
例如:

class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.listRef}>{/* ...contents... */}</div>
    );
  }
}
void componentDidUpdate()

組件更新之后調(diào)用骏掀,除了首次render之后調(diào)用componentDidMount,其它render結(jié)束之后都是調(diào)用componentDidUpdate。

void componentWillUnmount()

組件被卸載的時候調(diào)用截驮。一般在componentDidMount里面注冊的事件需要在這里刪除笑陈。

void componentDidCatch(error, info)

可以捕獲其子組件樹和當(dāng)前生命周期里面的任何js錯誤,然后可以通過setState()顯示錯誤的UI界面

更新方式

  1. 首次渲染Initial Render
  2. 調(diào)用this.setState (并不是一次setState會觸發(fā)一次render葵袭,React可能會合并操作涵妥,再一次性進(jìn)行render)
  3. 父組件發(fā)生更新(一般就是props發(fā)生改變,但是就算props沒有改變或者父子組件之間沒有數(shù)據(jù)交換也會觸發(fā)render)
  4. 調(diào)用this.forceUpdate

React16.3版本以前的


React生命周期16.3.png

React16.4版本以后的


React生命周期16.4.png

一個React組件生命周期的測試?yán)?/h3>
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class TestLifeCircle extends Component {
  constructor() {
    super();
    alert('constructor');
    this.state = { name: 'Li Si' };
  }

  // componentWillMount() {
  //   alert('componentWillMount');
  // }
  componentDidMount() {
    alert('componentDidMount');
  }
  componentWillUnmount() {
    alert('componentWillUnmount')
  }

  // componentWillReceiveProps(nextProps) {
  //   alert('componentWillReceiveProps');
  // }

  shouldComponentUpdate(nextProps, nextState) {
    alert('shouldComponentUpdate');
    return true;
  }

  // componentWillUpdate() {
  //   alert('componentWillUpdate');
  // }

  componentDidUpdate() {
    alert('componentDidUpdate');
  }

  static getDerivedStateFromProps(props, state) {
    console.log('getDerivedStateFromProps: ', props, state);
    alert('getDerivedStateFromProps');
  }

  getSnapshotBeforeUpdate() {
    alert('getSnapshotBeforeUpdate');
  }

  setTheState() {
    this.setState({ name: 'Zhang San' });
  }

  forceLifeCycleUpdate() {
    this.forceUpdate();
  }

  render() {
    alert('render');
    const { name } = this.state;
    return (
      <div>
        <div>Welcome {name}!</div>
      </div>
    );
  }
}

class App extends Component {
  constructor() {
    super();
    this.state = {};
  }

  parentSetState() {
    this.refs.testLifeCircle.setTheState();
  }

  propsUpdate() {
    this.setState({ data: '123' });
  }

  parentForceUpdate() {
    this.refs.testLifeCircle.forceLifeCycleUpdate();
  }
  unmount() {
    ReactDOM.unmountComponentAtNode(document.getElementById("app"));
  }
  
  render() {
    return (
      <div>
        <div><button onClick={this.parentSetState.bind(this)}>setState</button></div>
        <div><button onClick={this.propsUpdate.bind(this)}>props update</button></div>
        <div><button onClick={this.parentForceUpdate.bind(this)}>forceUpdate</button></div>
        <div><button onClick={this.unmount.bind(this)}>unmount</button></div>
        <TestLifeCircle ref="testLifeCircle" />
      </div>
    );
  }
}

ReactDom.render(
    <App />,
    document.getElementById('app')
);

參考:React組件生命周期小結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坡锡,一起剝皮案震驚了整個濱河市妹笆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌娜氏,老刑警劉巖拳缠,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贸弥,居然都是意外死亡窟坐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門绵疲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哲鸳,“玉大人,你說我怎么就攤上這事盔憨♂悴ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵郁岩,是天一觀的道長婿奔。 經(jīng)常有香客問我,道長问慎,這世上最難降的妖魔是什么萍摊? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮如叼,結(jié)果婚禮上冰木,老公的妹妹穿的比我還像新娘。我一直安慰自己笼恰,他們只是感情好踊沸,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著社证,像睡著了一般逼龟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上猴仑,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天审轮,我揣著相機(jī)與錄音,去河邊找鬼辽俗。 笑死疾渣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的崖飘。 我是一名探鬼主播榴捡,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼朱浴!你這毒婦竟也來了吊圾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤翰蠢,失蹤者是張志新(化名)和其女友劉穎项乒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梁沧,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡檀何,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了廷支。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片频鉴。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖恋拍,靈堂內(nèi)的尸體忽然破棺而出垛孔,到底是詐尸還是另有隱情,我是刑警寧澤施敢,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布周荐,位于F島的核電站,受9級特大地震影響僵娃,放射性物質(zhì)發(fā)生泄漏羡藐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一悯许、第九天 我趴在偏房一處隱蔽的房頂上張望仆嗦。 院中可真熱鬧,春花似錦先壕、人聲如沸瘩扼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽集绰。三九已至,卻和暖如春谆棺,著一層夾襖步出監(jiān)牢的瞬間栽燕,已是汗流浹背罕袋。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留碍岔,地道東北人浴讯。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像蔼啦,于是被迫代替她去往敵國和親榆纽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

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

  • 一個react組件在瀏覽器中存在三種狀態(tài):1(組件掛載)Mounting 2(組件更新)Updating 3(組件...
    hello_water閱讀 1,517評論 0 2
  • 說在前面 關(guān)于 react 的總結(jié)過去半年就一直碎碎念著要搞起來捏肢,各(wo)種(tai)原(lan)因(le)奈籽。心...
    陳嘻嘻啊閱讀 6,850評論 7 41
  • 即使最近還是有點拖延,可還是再看一些關(guān)于React的東西鸵赫∫缕粒看到React組件的生命周期的時候,讓我想到了Vue同樣...
    白霽閱讀 594評論 0 9
  • 目前辩棒,react組件有三種寫法勾拉,分別是es5的createClass寫法,es6的class寫法盗温,以及statel...
    ZoomFunc閱讀 1,628評論 0 1
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南藕赞,這只是我在學(xué)習(xí)過程中的一些閱讀筆記,個人覺得該教程講解深入淺出卖局,比目前大...
    leonaxiong閱讀 2,813評論 1 18