React的生命周期

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

函數(shù) / 方法

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

// 定義一個(gè)TodoList的React組件,通過(guò)繼承React.Component來(lái)實(shí)現(xiàn)
class TodoList extends React.Component {
  ...
}

class的定義方法

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

class中的構(gòu)造器,主要功能是初始化一些變量(state等)并繼承父類(lèi)(父組件)的屬性,需要注意的是React組件中如果有定義constructor函數(shù)就必須要寫(xiě)super(),而constructor里面如果要使用this.props的話(huà)就要super(props),但是就算不寫(xiě)也不影響其他函數(shù)使用props因?yàn)镽eact會(huì)自動(dòng)傳入。

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

渲染頁(yè)面,由于setState會(huì)觸發(fā)render,所以不要在這里面setState。

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

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

void componentDidMount()

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

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

父組件發(fā)生更新時(shí)被調(diào)用(不管props有沒(méi)有更新,也不管父子組件之間有沒(méi)有數(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)用,第一次初始化和無(wú)論何種方式更新組件都會(huì)調(diào)用此方法, 要注意的是 要加static

getSnapshotBeforeUpdate() // 16.3++版本

頁(yè)面之前的dom元素還沒(méi)改變之前調(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()

組件被卸載的時(shí)候調(diào)用。一般在componentDidMount里面注冊(cè)的事件需要在這里刪除。

void componentDidCatch(error, info)

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

更新方式

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

React16.3版本以前的


React生命周期16.3.png

React16.4版本以后的


React生命周期16.4.png

一個(gè)React組件生命周期的測(cè)試?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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一個(gè)react組件在瀏覽器中存在三種狀態(tài):1(組件掛載)Mounting 2(組件更新)Updating 3(組件...
    hello_water閱讀 1,916評(píng)論 0 2
  • 說(shuō)在前面 關(guān)于 react 的總結(jié)過(guò)去半年就一直碎碎念著要搞起來(lái),各(wo)種(tai)原(lan)因(le)。心...
    陳嘻嘻啊閱讀 7,035評(píng)論 7 41
  • 即使最近還是有點(diǎn)拖延,可還是再看一些關(guān)于React的東西??吹絉eact組件的生命周期的時(shí)候,讓我想到了Vue同樣...
    白霽閱讀 636評(píng)論 0 9
  • 目前,react組件有三種寫(xiě)法,分別是es5的createClass寫(xiě)法,es6的class寫(xiě)法,以及statel...
    ZoomFunc閱讀 1,911評(píng)論 0 1
  • 原教程內(nèi)容詳見(jiàn)精益 React 學(xué)習(xí)指南,這只是我在學(xué)習(xí)過(guò)程中的一些閱讀筆記,個(gè)人覺(jué)得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,944評(píng)論 1 18

友情鏈接更多精彩內(nèi)容