React-生命週期的認識

認識到的React生命週期分爲React16.0 之前的生命週期和React16.0之後的生命週期

React16.0 版本之前的生命週期

static defaultProps = {};
static propTypes = {};

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

componentWillMount() {}

render() {}

componentDidMount() {}

組件運行時

組件運行時生命週期

constructor(props) {
    super(props);
    // 常用於初始化狀態
    console.log("1.組件構造函數執行");
  }
  componentWillMount() {
    // 此時可以訪問狀態和屬性,可進行api調用等
    console.log("2.組件將要掛載");
  }
  componentDidMount() {
    // 組件已掛載,可進行狀態更新操作
    console.log("3.組件已掛載");
  }
  componentWillReceiveProps(nextProps) {
    // 父組件傳遞的屬性有變化,做相應響應
    console.log("4.將要接收屬性傳遞");
  }
  shouldComponentUpdate(nextProps, nextState) {
    // 組件是否需要更新,需要返回布爾值結果,優化點
    console.log("5.組件是否需要更新?");
    return true;
  }
  componentWillUpdate(nextProps, nextState) {
    // 組件將要更新,可做更新統計
    console.log("6.組件將要更新");
  }
  componentDidUpdate(prevProps, prevState) {
    // 組件更新
    console.log("7.組件已更新");
  }
  componentWillUnmount() {
    // 組件將要卸載, 可做清理工作
    console.log("8.組件將要卸載");
  }
  render() {
    console.log("組件渲染");
    return <div>生命週期探究</div>;
  }

==

  • 只有在 render 和 componentDidUpdate 中才能獲取到更新後的 this.state
  • 在函數(componentWillReceiveProps)中調用 this.setState() 將不會引起第二次渲染
  • 禁止在 shouldComponentUpdate 和 componentWillUpdate 中調用 setState,這會造成循環調用,直至耗光瀏覽器內存後崩潰。

組件的生命週期在不同狀態下的執行順序

  • 當首次掛載組件時,按順序執行
    getDefaultProps、getInitialState、componentWillMount、render 和
    componentDidMount

  • 當卸載組件時,執行 componentWillUnmount 當重新掛載組件時,此時按順序執行

    getInitialState、componentWillMount、render 和componentDidMount,但並不執行
    getDefaultProps

  • 當再次渲染組件時,組件接受到更新狀態,此時按順序執componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render 和 componentDidUpdate

當使用 ES6 classes 構建 React 組件時,static defaultProps = {} 其實就是調用內部的 getDefaultProps方法,constructor 中的 this.state = {} 其實就是調用內部的 getInitialState 方法

React16.4 的生命週期

在這裏插入圖片描述

  • getDerivedStateFromProps

React v16.3 getDerivedStateFromProps無論是Mounting還是Updating,也無論是因爲什麼引起的Updating,全部都會被調用

React v16.4 static getDerivedStateFromProps(props, state)
在組件創建時和更新時的render方法之前調用,它應該返回 一個對象來更新狀態,或者返回null來不更新任何內容。

  • getSnapshotBeforeUpdate

getSnapshotBeforeUpdate() 被調用於render之後,可以讀取但無法使用DOM的時候。
它使您的組件可以在可能更改之前從DOM捕獲一些信息(例如滾動位置)。此生命週期返回的任何值都將作爲參數傳遞給componentDidUpdate()。

官網示例

class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }
  getSnapshotBeforeUpdate(prevProps, prevState) { //我們是否要添加新的 items 到列表?
    // 捕捉滾動位置,以便我們可以稍後調整滾動.
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }
  componentDidUpdate(prevProps, prevState, snapshot) { //如果我們有snapshot值, 我們已經添加了 新的items.
    // 調整滾動以至於這些新的items 不會將舊items推出視圖。
    // (這邊的snapshot是 getSnapshotBeforeUpdate方法的返回值) 
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.listRef}>{/* ...contents... */}</div>
    );
  }
}
constructor(props) {
    super(props);
    this.state = {
      visible: false,
    }
    console.log('constructor')
  }

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

  componentDidMount() {
    console.log('componentDidMount');
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log('shouldComponentUpdate', nextProps, nextState)
  }
  
  getSnapshotBeforeUpdate = (prevProps, prevState) => {
    console.log('getSnapshotBeforeUpdate', prevProps, prevState);
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('componentDidUpdate', prevProps, prevState);
  }
  
  componentWillUnmount() {
    console.log('componentWillUnmount');
  }
  
  render() {
    console.log('render');
    return (
      <div></div>
    )
  }

文章參考:
1、From TaobaoFED 【I like his website】高性能 React 組件

http://taobaofed.org/blog/2016/08/12/optimized-react-components/

2、什麼時候要在 React 組件中寫 shouldComponentUpdate

https://infoq.cn/article/2016/07/react-shouldComponentUpdate

3、【喜歡這篇文章講解的生命週期】 react如何通過shouldComponentUpdate來減少重複渲染

https://segmentfault.com/a/1190000016494335

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章