React 的生命周期

发布于 2021-12-18 18:31:18 字数 3794 浏览 1095 评论 0

什么是生命周期方法

生命周期方法可以理解为发生在 React 组件从生到死的各阶段的事件。

组件的生命周期又可以分为三阶段:

  • Mounting 出生
  • Update 生长
  • Unmounted 死亡

生命周期方法概观

如下截图是来自 react-lifecycle-methods-diagram,它列举了生命周期中的重要方法:

react-lifecycle-diagram

生命周期方法详解

static getDerivedStateFromProps()

该方法会在 Mounting 和 Update 阶段,就每次 render 调用之前被调用(如果有声明的话)。

一旦 prop 发生改变,它就会更新 state,相应的它的调用结果会是一个对象,如果没有任何改变被应有到 state,则返回 null。

由于它是个静态方法,不需要通过 this 来获取实例。如下是一个示例:

static getDerivedStateFromProps(props, state) {
    if (props.currentRow !== state.lastRow) {
      return {
        isScrollingDown: props.currentRow > state.lastRow,
        lastRow: props.currentRow,
      };
    }
    // Return null to indicate no change to state.
    return null;
}

render()

render 方法唯一一个组件中必须包含的方法,它的作用是渲染组件到 UI,它会发生在MountingUpdate阶段。

render 方法必须是纯净

即它在同样的输入(props 和 state)条件下,调用的结果是完全一样的。这意味着,你不能在 render 方法中调用 setState。

保持 render 方法的简单和 纯净 让你的应用更可控。

componentDidMount

组件被挂载就位以后的事件是 componentDidMount,你可以在这里初始化 API 的调用。

你可以在该方法中调用 setState 方法,调用会导致state更新,进而导致一次新的绘制。

不过它会在浏览器完成当前这次UI的更新后才开始,从而避免同时进行两次UI的更新。

谨慎使用 setState

最好的初始 state 的做法是在 constructor 中,要使用它的原因应该是诸如:tooltip、modals 或者类似的你需要根据 DOM 节点位置来决定渲染效果。

shouldComponentUpdate

当你不想让 React 重新根据 state 和 props 渲染的时候,可以使用这个方法。

它应该被谨慎地应用于性能优化中,并且不应该过度依赖他,因为他可能导致一些bug。

你不能在该方法中更新 state。

shouldComponentUpdate(nextProps, nextState) {
 return this.props.title !== nextProps.title || 
  this.state.input !== nextState.input }

上述例子表明,该方法应该始终放回一个布尔值,用于告诉 React 是否应该重新渲染组件。

getSnapshotBeforeUpdate

该方法在 DOM 被更新后会马上被调用,调用的返回值会被传递给 componentDidUpdate 方法。

同样需要注意的是,这个方法不应该被频繁使用。

getSnapshotBeforeUpdate(prevProps, prevState) {
    // ...
}

componentDidUpdate

组件更新完成后会马上调用该方法,你可以在该方法中使用setState,但是应该带上条件,否则会导致死循环。

componentDidUpdate(prevProps) {
 //Typical usage, don't forget to compare the props
 if (this.props.userName !== prevProps.userName) {
   this.fetchData(this.props.userName);
 }
}

omponentWillUnmount()

方法会在组件被卸载并且销毁的时候调用,你可以做一些诸如清除timers, 结束API调用, 清理缓存等操作。

同样我们不能在它上面调用setState因为组件被再次渲染。

生命周期方法总结

参考上节中的图,可以看到在渲染过程又分为三个时间阶段

Render 阶段

流程可能是下面两种序列:

constructor -> getDerivedStateFromProps -> render

constructor -> getDerivedStateFromProps -> shouldComponentUpdate -> render


constructor:用于初始化state

getDerivedStateFromProps:通过返回对象用于基于props增强state

shouldComponentUpdate:通过返回boolean用于性能优化减少React的组件更新

render:用于绘制DOM


该阶段的是”纯净“的,出了前两个会初始state,后两个之负责调整流程 和 绘制。

Pre-commit 阶段

可以理解为它是DOM被渲染完成之前的几个阶段,仅有一个方法 getSnapshotBeforeUpdate可以用,可以让你获取到上次的props和state并将结果返回给componentDidMount。

Commit 阶段

如果是在Mounting流程中,包含componentDidMount方法。
如果是在Updating流程中,包含componentDidUpdate方法。

上述两个方法都可以调用setState的,但是应该谨慎使用,避免死循环。


如果是在 Unmounting 阶段,包含 componentWillUnmount 方法。

不能调用setState,适宜做一些清理timer、取消API调用、清除缓存的事情。

参考资料

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

辞别

暂无简介

文章
评论
544 人气
更多

推荐作者

微信用户

文章 0 评论 0

小情绪

文章 0 评论 0

ゞ记忆︶ㄣ

文章 0 评论 0

笨死的猪

文章 0 评论 0

彭明超

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文