【React 资料备份】React v16.3以后的生命周期

React v16.4 的生命周期图服务器

img

React v16.4 的生命周期async

变动原因

原来(React v16.0前)的生命周期在React v16推出的Fiber以后就不合适了,由于若是要开启async rendering,在render函数以前的全部函数,都有可能被执行屡次。函数

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

  • componentWillMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate

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

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

也就是用一个静态函数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 的生命周期图get

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>
    );
  }
相关文章
相关标签/搜索