zoukankan      html  css  js  c++  java
  • 【React 资料备份】React v16.3之后的生命周期

    React v16.4 的生命周期图

    img

    React v16.4 的生命周期

    变更缘由

    原来(React v16.0前)的生命周期在React v16推出的Fiber之后就不合适了,因为如果要开启async rendering,在render函数之前的所有函数,都有可能被执行多次。

    原来(React v16.0前)的生命周期有哪些是在render前执行的呢?

    • componentWillMount
    • componentWillReceiveProps
    • shouldComponentUpdate
    • componentWillUpdate

    如果开发者开了async rendering,而且又在以上这些render前执行的生命周期方法做AJAX请求的话,那AJAX将被无谓地多次调用。。。明显不是我们期望的结果。而且在componentWillMount里发起AJAX,不管多快得到结果也赶不上首次render,而且componentWillMount在服务器端渲染也会被调用到(当然,也许这是预期的结果),这样的IO操作放在componentDidMount里更合适。

    禁止不能用比劝导开发者不要这样用的效果更好,所以除了shouldComponentUpdate,其他在render函数之前的所有函数(componentWillMount,componentWillReceiveProps,componentWillUpdate)都被getDerivedStateFromProps替代。

    也就是用一个静态函数getDerivedStateFromProps来取代被deprecate的几个生命周期函数,就是强制开发者在render之前只做无副作用的操作,而且能做的操作局限在根据props和state决定新的state

    React v16.0刚推出的时候,是增加了一个componentDidCatch生命周期函数,这只是一个增量式修改,完全不影响原有生命周期函数;但是,到了React v16.3,大改动来了,引入了两个新的生命周期函数。

    新引入了两个新的生命周期函数:getDerivedStateFromPropsgetSnapshotBeforeUpdate

    getDerivedStateFromProps

    getDerivedStateFromProps本来(React v16.3中)是只在创建和更新(由父组件引发部分),如果不是由父组件引发,那么getDerivedStateFromProps也不会被调用,如自身setState引发或者forceUpdate引发。

    React v16.3 的生命周期图

    img

    React v16.3

    这样的话理解起来有点乱,在React v16.4中改正了这一点,让getDerivedStateFromProps无论是Mounting还是Updating,也无论是因为什么引起的Updating,全部都会被调用,具体可看React v16.4 的生命周期图。

    React v16.4后的getDerivedStateFromProps

    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>
        );
      }
    
  • 相关阅读:
    IELTS Writing Task 2: 'music' essay
    leetcode 368. 最大整除子集
    820复试算法 快排找第 k 小
    ASP.NET后台生成随机验证码
    Oracle身份证验证方法
    ASP.NET 存储过程导入(oracle)返回导入成功数和导入失败数
    C#执行参数为游标 返回一个记录集的Oracle存储过程
    C#执行带参数的Oracle存储过程
    往ORACLE数据库中插入XML数据
    存储过程 将数据插入到临时表,再根据条件判断 插入到不同的表
  • 原文地址:https://www.cnblogs.com/horanly/p/10476052.html
Copyright © 2011-2022 走看看