likes
comments
collection
share

谈谈 React V16.4 的生命周期

作者站长头像
站长
· 阅读数 39

前言

我们在谈 React 生命周期时,主要谈的是 类式组件的生命周期,因为函数式组件是没有生命周期函数的。(我们可以通过 hooks 来模拟一些生命周期的回调)

React 生命周期在各个阶段的执行顺序是有所差异的,接下来我们将解析 React 在各个阶段生命周期的执行顺序,以及各个生命周期在组件中充当的作用。(以下生命周期指的是 React 16.4 之后的版本)

谈谈 React V16.4 的生命周期

React 生命周期图:React 生命周期图

组件挂载时

当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

  • constructor()

  • static getDerivedStateFromProps()

  • render()

  • componentDidMount()

constructor()

如果不初始化 state 或不进行方法绑定,则不需要为 class 组件实现构造函数。在 React 中,通常构造函数仅用于以下两种情况:

  1. 通过给 this.state 赋值对象来初始化内部 state

  2. 为事件处理函数绑定实例。

在 React 组件挂载之前,会调用它的构造函数。在为子类实现构造函数时,应在其他语句之前调用 super(props)。否则 this.props 在构造函数中可能会出现未定义的 bug。

在 constructor() 函数中不要调用 setState() 方法,如果你的组件需要使用内部 state,请直接在构造函数中为 this.state 赋值初始 state

render()

render() 方法是 class 组件中唯一必须实现的方法。render() 函数应该为 纯函数,这意味着在不修改组件 state 的情况下,每次调用时都返回相同的结果,并且它不会直接与浏览器交互。如需与浏览器进行交互,请在 componentDidMount() 或其他生命周期方法中执行操作。

componentDidMount()

componentDidMount() 会在 组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如果需要通过网络请求获取数据,此处是实例化请求的好地方。

你可以在 componentDidMount() 中直接调用 setState() 方法。

hooks 模拟 componentDidMount()

useEffect(() => console.log("mounted"), []);

useEffect 的第二个参数是一个空数组时,回调只会被触发一次(即组件挂载后执行),类似于 componentDidMount()

组件更新时

当组件的 propsstate 发生变化时会触发更新。组件更新的生命周期调用顺序如下:

  • static getDerivedStateFromProps()

  • shouldComponentUpdate()

  • render()

  • getSnapshotBeforeUpdate()

  • componentDidUpdate()

componentDidUpdate()

componentDidUpdate() 会在 组件更新后立即调用。首次渲染不会执行此方法。

当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(当 props 未发生变化时,则不会执行网络请求)。

你也可以在 componentDidUpdate() 中直接调用 setState() 方法,但需注意 它必须被包裹在一个条件语句里

hooks 模拟 componentDidUpdate()

const mounted = useRef();

useEffect(() => {
  if (!mounted.current) {
    mounted.current = true;
  } else {
    console.log("updated");
  }
});

使用 useRef 创建实例,它作为一个标志来指示组件是否处于挂载或更新阶段。当组件更新完成后在会执行 else 里面的内容,以此来模拟 componentDidUpdate()

组件卸载时

当组件从 DOM 中移除时会调用方法:componentWillUnmount()

componentWillUnmount()

componentWillUnmount() 会在 组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如清除定时器,取消网络请求或者清除在 componentDidMount() 中创建的订阅等。

componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。

hooks 模拟 componentWillUnmount()

useEffect(() => {
  return () => {
    console.log("will unmount");
  };
}, []);

当在 useEffect 的回调函数中返回一个函数时,这个函数会在组件卸载前被调用。我们可以在这里面清除定时器或事件监听器。

错误处理

在渲染过程中,生命周期或子组件的构造函数中抛出错误时,会调用如下方法:

  • static getDerivedStateFromError()

  • componentDidCatch()

参考:zh-hans.reactjs.org/docs/react-…

最后

文中笔者对 React V16.4 中一些常见的生命周期做了介绍,对于不常用的生命周期的介绍大家可以参考官方文档,如果对你有帮助的话,不要忘了点赞哟~

转载自:https://juejin.cn/post/7203239282210324537
评论
请登录