《React+Redux前端开发实战》—2.4.5 老版React中的生命周期

举报
华章计算机 发表于 2019/07/24 23:52:01 2019/07/24
【摘要】 本节书摘来自华章计算机《React+Redux前端开发实战》一书中的第2章,第2.4.5节,作者是徐顺发.

2.4.5  老版React中的生命周期

  老版本的React中还有如下生命周期:

  •  componentWillMount();

  •  componentWillReceiveProps();

  •  componentWillUpdate()。

  老版本中的部分生命周期方法有多种方式可以完成一个任务,但很难弄清楚哪个才是最佳选项。有的错误处理行为会导致内存泄漏,还可能影响未来的异步渲染模式等。鉴于此,React决定在未来废弃这些方法。

  React官方考虑到这些改动会影响之前一直在使用生命周期方法的组件,因此将尽量平缓过渡这些改动。在React 16.3版本中,为不安全生命周期引入别名:

  •  UNSAFE_componentWillMount;

  •  UNSAFE_componentWillReceiveProps;

  •  UNSAFE_componentWillUpdate。

  旧的生命周期名称和新的别名都可以在React16.3版本中使用。将要废弃旧版本的生命周期会保留至React 17版本中删除。

  同时,React官方也提供了两个新的生命周期:

  •  getDerivedStateFromProps();

  •  getSnapshotBeforeUpdate()。

  getDerivedStateFromProps()生命周期在组件实例化及接收新props后调用,会返回一个对象去更新state,或返回null不去更新,用于确认当前组件是否需要重新渲染。这个生命周期将可以作为componentWillReceiveProps()的安全替代者。

  getDerivedStateFromProps()生命周期示例:

  

  class App extends React.Component {

    static getDerivedStateFromProps(nextProps, prevState) {

      ...

    }

  }

  

  getSnapshotBeforeUpdate()生命周期方法将在更新之前被调用,比如DOM被更新之前。这个生命周期的返回值将作为第3个参数传递给componentDidUpdate()方法,虽然这个方法不经常使用,但是对于一些场景(比如保存滚动位置)非常有用。配合componentDidUpdate()方法使用,新的生命周期将覆盖旧版componentWillUpdate()的所有用例。

  getSnapshotBeforeUpdate()生命周期(官方示例):

  

  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;

    }

    componentDidUpdate(prevProps, prevState, snapshot) {

      // 如果有新值,就添加进新项目

      // 调整滚动位置,新项目不会把老项目推到可视窗口外

      // (这里的snapshot来自于getSnapshotBeforeUpdate()这个生命周期的返回值)

      if (snapshot !== null) {

        const list = this.listRef.current;

        list.scrollTop = list.scrollHeight - snapshot;

      }

    }

    render() {

      return (

        <div ref={this.listRef}>{/* ...contents... */}</div>

      );

    }

  }


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。