6

组件更新

  • static getDerivedStateFromProps()

    当本地state需要根据props来改变的时候可调用此方法。

    这个方法是在render()前会被执行,只要执行render()都会被在之前被触发。

    该方法有两个参数propsstate; 返回值为state对象, 不需要返回整体state,把需要改变的state返回即可。

    示例:

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

    此方法有两个参数:shouldComponentUpdate(nextProps, nextState).

    返回值为true或者false, 默认返回true.

    主要使用它来控制组件要不要渲然,常用作性能优化。

    触发此方法的条件是:组件接收任意props或者state时都会被调用。需要注意的是在第一次render()时和在调用forceUpdate()时都不会被触发。

    示例:

    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 手稿》


小翼
5.9k 声望9.9k 粉丝

React 第一本手稿级的文档。