谈谈 React V16.4 的生命周期
前言
我们在谈 React 生命周期时,主要谈的是 类式组件的生命周期,因为函数式组件是没有生命周期函数的。(我们可以通过 hooks 来模拟一些生命周期的回调)
React 生命周期在各个阶段的执行顺序是有所差异的,接下来我们将解析 React 在各个阶段生命周期的执行顺序,以及各个生命周期在组件中充当的作用。(以下生命周期指的是 React 16.4 之后的版本)

React 生命周期图:React 生命周期图
组件挂载时
当组件实例被创建并插入 DOM
中时,其生命周期调用顺序如下:
-
constructor()
-
static getDerivedStateFromProps()
-
render()
-
componentDidMount()
constructor()
如果不初始化 state
或不进行方法绑定,则不需要为 class 组件实现构造函数。在 React 中,通常构造函数仅用于以下两种情况:
通过给
this.state
赋值对象来初始化内部state
。为事件处理函数绑定实例。
在 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()
。
组件更新时
当组件的 props
或 state
发生变化时会触发更新。组件更新的生命周期调用顺序如下:
-
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