如何恰当地使用 React 生命周期方法

对于 React 生命周期方法,如果你不清楚什么情况下该使用哪一个方法,可能会感到困扰。今天,我将向你展示存在哪些生命周期方法以及该如何使用它们。

介绍

React 组件拥有几个“生命周期方法”(lifecycle methods),它们允许我们在特定的时间点执行一些 actions(例如:从 server 请求数据)。当我开始学习 React 时,我发现很难弄清楚我应该为某些操作(actions)使用哪种生命周期方法。如果你也是这样,这篇文章应该是一个不错的指南。

我将从所有生命周期方法的概述开始,并按照它们的调用顺序来进行说明。然后我将用简短的额解释和一些例子来阐释它们。在最后,你应该对何时使用何种生命周期方法有一个更好的理解。

一个 React 组件的生命周期

根据 React 文档,我们从组件的生命周期开始。组件的生命周期中有三个特定的阶段,它们对我们的生命周期方法很重要,我将会一一解释:

  • Mount(挂载)
  • Update(更新)
  • Unmount(卸载)

Mount

当 React 创建一个组件实例并将其插入到 DOM 中(mounting),将调用一下方法:

  • constructor()
  • componentWillMount()
  • render()
  • conponentDidMount()

Update

如果一个组件的 props 或 state 发生变化,无论什么原因,组件都将会进行 update。不管怎么样,这意味着组件将被重新渲染,所有,以下的方法将被调用:

  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()

Unmount

有些时候,我们的组件要从 DOM 中移除。这个过程被称作 unmounting,这意味着以下的方法将被调用:

  • componentWillUnmount()

React 组件生命周期总结

我希望我已经让你对 React 组件的生命周期以及生命周期方法调用顺序有了一个大概的了解。这是为了简洁,这里列出了生命周期方法正确的调用顺序:

  • componentWillMount()
  • componentDidMount()
  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • componentDidUpdate()
  • componentWillUnmount()

你可以看到,它们不是很多。但是,重要的是你可以为不同的用例选择正确的那个方法来防止副作用或错误。

生命周期方法

这一节,我们将会探讨不同的生命周期方法。我将会对每一个方法进行详细的解释,并且,为了更好理解,我会尽量提供不同的示例来解释它们的使用场景。

componentWillMount()

componentWillMount()

每当 React 渲染一个组件,它将首先调用 componentWillMount。请注意,该方法在组件的生命周期中仅被调用一次,而且是在初始化之前,所以,这时是无法访问 DOM 的。

Note: 因为 componentWillMount 在 render() 之前被调用,所以当你使用服务端渲染时,这是在服务端能够调用的唯一的生命周期方法。

对于生命周期钩子,React 文档建议使用 constructor 代替。

State

在这个方法中,你可以使用 this.setState() 。但是,请注意,当你在同步设置 state 时,可能不会触发重新渲染。

如果可以的话,我建议在构造函数中设置默认的 state,而不是在这是设置 state。

Use cases

我没有为 componentWillMount 找到很多示例。有些人建议用它来做一些只能在运行时执行的根组件的配置(例如:设置 Firebase 的链接)。有些人会在这里进行 AJAX 请求,加载组件的数据。不要这样做,会有更合适的处理位置的。

componentDidMount()

componentDidMount()

这个方法无论何时被调用,React 已经渲染了我们的组件并且将它放入到了 DOM 中。因此,如果要执行任何依赖于 DOM 的初始化,请在此处执行。

state

你可以用this.setState()设置 state。每当你这样做,它将触发组件的重新渲染。

Use Cases

你可以在 componentDidMount 中使用 AJAX 向服务请求数据。另外,如果你需要初始化依赖 DOM 的东西,你可以在此进行操作(例如:初始化第三方库,如 D3)。最后,但并没有完,你可以在 componentDidMount 中添加事件监听。

componentWillReceiveProps()

componentWillReceiveProps()

每当一个组件接收到一组新的 props,这个方法将被首先调用。另外请注意,即使 props 没有改变,React 也会调用这个方法。所以,每当使用这个方法时,一定要将 this.props 与 nextProps 进行比较,以避免不必要的状态设置。

 mount 的过程中,React 没有调用这个方法。相反,如果组件的某些 props 发生 update,它只会调用这个方法。

State

通过 this.setState() 可以设置 state。

Use Case

如果你有一个 state 是通过多个 props 计算获得的,你可以在这里做这个计算。不要忘记检查相关的 props 是否真的发生了改变(比较 this.props  nextProps)。

shouldComponentUpdate()

shouldComponentUpdate()

默认情况下,此方法没有实现,因此每次 state 或 props 更新都会导致渲染,即使 props 没有改变。但是,如果你想要变美不必要的渲染,你可以在这里进行处理。这个方法返回 false,意味着 React 将不会执行 componentWillUpdate(), render(), 和 componentDidUpdate()。

初始化渲染的时候,这个方法不会被调用。

注意: 根据 React 的文档,React 对待 shouldComponentUpdate 就像对待一个提示一样,而不是严格遵循它的返回值。这意味着,即使该方法返回 false,但是,React 可能仍然会重新渲染组件。

State

在这儿,你不能调用 setState。此外,这样做是没有意义的。如果因为 props 的改变要设置 state,请改用 componentWillReceiveProps。

Use Case

如前所述,你可以检查 props 或 state 的更新是否确实影响到了组件的输出。你可以通过对现在的 props/state 和 下一个 props/state 进行比较来得出结论。如果组件不应该更新,只需返回 false,组件将不会更新。

Note: 这可能会导致严重的副作用。React 还为这种情况提供了另一种解决方案:如果你注意到某个组件较慢,则可以从 React.PureComponent 继承,而不是从 React.Component 继承。它将对 props 和 state 进行浅层的比较,这可能适用于我现在可以想象到的大多数情况。

componentWillUpdate()

componentWillUpdate()

在渲染之前调用此方法。像 shouldComponentUpdate 一样,只要有新的 props 传递给组件,或者 state 改变,就会调用它。

初始渲染不会调用此方法。

State

在这你不能调用 setState。再一次提醒,如果你因为 props 的改变要重新设置 state,那么用 componentWillReceiveProps 来代替吧。

Use Case

你可以在更新组件之前执行需要完成的准备工作。这个生命周期方法在 render() 之前被调用,所以你不能做任何依赖于 DOM 的事情——它很快就会过时了。

常见使用示例应该有:

  • 根据 state 的变化设置一个变量
  • 调用事件
  • 开始动画

componentDidUpdate()

componentDidUpdate(prevProps, prevState)

好极了!一切顺利,React 更新了我们的组件。在渲染后,React 会直接调用 componentDidUpdate。

初始渲染不会调用此方法。

State

你可以在这使用 setState

Use Case

如果在组件更新以后,你需要用 DOM 进行一些操作的时候,在这里再好不过了。一个很好的例子就是通过传递新的数据来更新像 D3 这样的第三方 UI 库。

这里也是一个进行网络请求的好地方,而且你可以比较 current state/props 和 previous state/props 来避免不必要的网络请求。

componentWillUnmount()

componentWillUnmount()

在 React 卸载和销毁我们的组件前,它会调用 componentWillUnmount

State

在卸载组件之前,你不能再设置 state。

Use Cases

使用这个钩子执行清除操作,可能是:

  • 移除你在 componentDidMount(或其它地方)添加的事件监听器
  • 注销活跃的网络请求
  • 废除 timers
  • 清除你在 componentDidMount 中创建的 DOM 元素

回顾

今天你已经学习到,React 组件的生命周期有三个部分组成:Mounting、Updating 和 Unmounting。
你也已经了解到,在每个阶段,React 都会调用哪些生命周期方法。你可以根据你的具体情况去使用它们。


作者:Andreas Reiterer
原文链接:传送门


猜你喜欢

转载自blog.csdn.net/tangxiaolang101/article/details/78124014