聊聊 React17.0 将要取消的组件三个生命周期函数

Remove componentWillMount, componentWillReceiveProps, and componentWillUpdate . (Only the new “UNSAFE_” lifecycle names will work from this point forward.)

从 React 官网博客中得知,React 将在 17.0 版本移除掉组件的三个生命周期函数。但是为了版本升级的平滑过渡,UNSAFE_开头的方法予以保留(既可以通过 UNSAFE_componentWillMount 使用)

These lifecycle methods have often been misunderstood and subtly misused; furthermore, we anticipate that their potential misuse may be more problematic with async rendering.

官网对于为何移除这三个生命周期函数给予了上面的说明,简单来说就是这三个生命周期函数容易被误解并滥用,可能会对异步渲染造成潜在的问题

所以,React 这次引入了两个新的生命周期函数来替代这三个生命周期函数,下面一起来看一下

getDerivedStateFromProps

从方法名上我们可以看出这个方法是用来根据传入的 props 来更新 state 的,这种场景我们在写项目中经常会遇到,比如一个 tab 组件的高亮。以前我们会使用 componentWillReceiveProps 来做判断,如果前后 props 不相等,然后就 setState 等等。 现在通过 getDerivedStateFromProps 方法,我们可以直接很方便的实现这种场景

static getDerivedStateFromProps(nextProps, prevState) {
	if (nextProps.pos !== prevState.pos) {
		return {
			pos: nextProps.pos
		}
	}
	return null
}

注意有几点,getDerivedStateFromProps 方法是一个 static 方法,意味着这个方法是属于 React.Component 类的方法,所以方法内是无法使用 this 的,这就意味着无法使用 this.setState 来更新 state,所以这个方法直接通过返回对象的形式来更新 state,如果某些 props 的情况不需要更新 state,那么就返回 null 就好。实际上这个方法和 componentDidUpdate 搭配使用,就能覆盖 componentWillReceiveProps 的所有使用场景了

getSnapshotBeforeUpdate

另外一个方法,首先它不是一个静态方法,从名字来看是在更新之前获取组件的快照。就是这样,这个方法会在组件更新前出发,它的返回值会作为第三个参数传递给后面的 componentDidUpdate 参数中,和 componentDidUpdate 一起使用,能覆盖掉 componentWillUpdate 的所有使用场景了

class ScrollingList extends React.Component {
  listRef = null;

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      return (
        this.listRef.scrollHeight - this.listRef.scrollTop
      );
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      this.listRef.scrollTop =
        this.listRef.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.setListRef}>
        {/* ...contents... */}
      </div>
    );
  }

  setListRef = ref => {
    this.listRef = ref;
  };
}

转载于:https://my.oschina.net/u/3117745/blog/1826850

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值