React16.3.0之後的生命週期(二) - 更新、卸載、異常

組件更新

  • static getDerivedStateFromProps()git

    當本地state須要根據props來改變的時候可調用此方法。github

    這個方法是在render()前會被執行,只要執行render()都會被在以前被觸發。web

    該方法有兩個參數propsstate; 返回值爲state對象, 不須要返回總體state,把須要改變的state返回便可。性能優化

    示例:dom

    static getDerivedStateFromProps(props, state) {
      if(props.color !== state.color) {
        return {color: props.color};
      }
    }
  • shouldComponentUpdate()函數

    此方法有兩個參數:shouldComponentUpdate(nextProps, nextState).性能

    返回值爲true或者false, 默認返回true.優化

    主要使用它來控制組件要不要渲然,經常使用做性能優化。this

    觸發此方法的條件是:組件接收任意props或者state時都會被調用。須要注意的是在第一次render()時和在調用forceUpdate()時都不會被觸發。code

    示例:

    shouldComponentUpdate(nextProps, nextState) {
      if(nextProps.color !== this.props.color || nextState.size !== this.state.size) {
        return true;
      } 
      return false;
    }
  • render()

    這個方法是React組件中必需要提供的方法。當state或者props任一數據有更新時都會執行。

    須要注意當繼承 PureComponent時,不會對對象進行深度比較,也就是,不會根據對象內的對象變化時執行 render().

    render()是一個純函數,也就是不能在這個方法中有相似setState()這樣的行爲。

    返回的數據類型能夠有:

    • nullStringNumberArrayBoolean
    • React elements
    • Fragment
    • Portal

      注意:不能返回 undefined.

shouldComponentUpdate()返回false時,不管stateprops有沒有變化,這個方法都不執行。

示例:

render() {
      return (
        <div>{this.state.color}</div>
      );
    }
  • getSnapshotBeforeUpdate()

    getSnapshotBeforeUpdate(prevProps, prevState)render將組件渲然到dom中就會執行。

    若是不實現該方法則返回null.

    返回的數據由本身定義,而且返回的數據做爲componentDidUpdate方法中的參數。

    示例:

    class ScrollingList extends React.Component {
      constructor(props) {
        super(props);
        this.listRef = React.createRef();
      }
    
      getSnapshotBeforeUpdate(prevProps, prevState) {
        if (prevProps.list.length < this.props.list.length) {
          const list = this.listRef.current;
          return list.scrollHeight - list.scrollTop;
        }
        return null;
      }
    
      render() {
        return (
          <div ref={this.listRef}>{/* ...contents... */}</div>
        );
      }
    }
  • componentDidUpdate()

    該方法在組件更新後當即執行,而且在組件掛載階段不執行。

    componentDidUpdate(prevProps, prevState, snapshot)第三個參數就是上節中提到的。

    示例:

    componentDidUpdate(prevProps, prevState, snapshot) {
        if (snapshot !== null) {
          const list = this.listRef.current;
          list.scrollTop = list.scrollHeight - snapshot;
        }
      }

組件卸載

  • componentWillUnmount()

    在組件被卸載或者銷燬的時候執行,方法中不能再有setState的動做。

    通常用做清除組件中起的定義器、webSocket等。

    示例:

    componentWillUnmount() {
      if(this.timer) {
        window.clearInterval(this.timer);
        this.timer = null;
      }
    }

    在線示例

組件異常處理

  • componentDidCatch()

    componentDidCatch(error, info) 異常的處理。

    只能捕獲組件樹的異常,沒法捕獲這個方法內的異常。

    示例:

    定義一下異常處理組件:

    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props);
        this.state = { hasError: false };
      }
    
      componentDidCatch(error, info) {
        this.setState({ hasError: true });
        window.console.log(error, info);
      }
    
      render() {
        if (this.state.hasError) {
          return <h1>Something went wrong.</h1>;
        }
        return this.props.children;
      }
    }

    使用這個異常組件:

    <ErrorBoundary>
      <MyWidget />
    </ErrorBoundary>

推薦閱讀《React 手稿》

相關文章
相關標籤/搜索