文章目录
本文篇幅较长,如果你想要:
- 完整了解整个组件生命周期的变更和对应函数API,那么请从头开始;
- 快速理解传统生命周期函数API的含义和使用,那么点击目录第二部分;
- 快速了解如何在函数组件中使用useEffect来替代原有的生命周期API,那么点击目录第三部分。
一、 引言
如果你是一名前端开发者,并且使用React开发框架,那么你一定绕不开React的一个核心概念——组件生命周期。 组件的生命周期描述的是一个组件从创建,渲染,加载,显示到卸载的整个过程。其大致过程如下:

图片来源请戳此链接:http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
我们从上图可以得知,一个组件主要包括三种行为,分别是:创建,更新,卸载。每个行为又可以划分为:Render 渲染阶段和 Commit 阶段 (更新时存在Pre-Commit 阶段)。这里先简单了解一下生命周期的概况,后文会进行详细描述。
React 官方开发者在生命周期的每个阶段都提供了相关的API,我们可以使用这些API定义组件在某个生命周期进行执行相关的行为。比较常用的就是使用componentDidMount API,在该函数内部获取来自服务器的数据。
学习这些API函数的使用并了解组件的生命周期的运行机制,是一个React开发者的基本功!
但是,我们必须不能只注重 API 的使用,而忽略了对生命周期的过程理解,API 只是 API,随时都有可能被替代!
这不,在 React v16.8 版本中,横空出世的 Hooks (俗称钩子)颠覆了之前的类组件范式,让函数组件逐渐成为主流,越来越多的团队开始考虑基于Hooks进行项目的重构,过去那种在类组件中调用各种生命周期API函数的方法将会慢慢成为过去(不过现在还是得学呀…)
本文不打算进行详述Hooks的用法及优越性,已经有许多优秀的前端团队对其展开了极富深度的论述啦,我只是一个刚入门不久的前端菜鸟,暂时难以从高层的视角来评判,如果你感兴趣,本文在第四部分推荐阅读给出一些高质量的链接,你可以学到更多。
回到主题。Hooks 提供了一套新的阐释组件生命周期的方式 ,原先许多生命周期的 API 都有了对应的 Hooks 解决方案——使用强大的useEffect这一Hooks函数。
综上,本文主要关注以下内容:
- 类组件生命周期理解和API用法;
- 如何在函数组件中使用
useEffect来替代类组件的生命周期API。
攥写本文的初衷是,本人最近在经常使用React框架开发,对生命周期这一核心概念有必要进行一番梳理,同时也发现网上关于讲解如何使用新特性Hooks来定制生命周期行为的博文数目较少而且不全面,所以我花费几个小时的时间来整理这些概念,总结方法并提供具体的代码实例,希望能帮助到大家,互相学习。
二、 组件生命周期过程及API详解
这里先放我从谷歌搜到的一张大家都在用的生命周期图(图源见链接),直接从API入手描述整个组件的生命周期过程,如果你已经使用过相关的API,那相当明了,但考虑到初学者,我还是基于个人理解给大家归纳总结一下,帮助大家理解、记忆和使用。

本文将API归为三类:
Mount:挂载APIUpdate: 更新APIUnmount:卸载API
结合上述流程图,我们从这三类API开始展开叙述,简单讲解一些不常用的API (不完全覆盖),多把文字放在常用的API(基本覆盖)上。
2.1 Mount
挂载一个组件的过程是先实例化创建该组件并渲染,然后读取DOM使得组件运行在浏览器中。整个过程涉及到的 API 函数如下:

当组件在客户端实例化首次创建时,以下方法依次被调用:
getDefaultProps(ES5语法,过时)getInitialState(ES5语法,过时)componentWillMount(弃用)render(必须使用)componentDidMount(常用)
当组件属于服务端渲染时,以下方法依次被调用:
getDefaultPropsgetInitialStatecomponentWillMountrender
服务端渲染没有 componentDidMount 方法时因为其执行阶段是组件挂载(插入DOM树)之后,才会执行,发生在客户端。
但需要提醒的是,getDefaultProps 和 getInitialState 方法仅适用于非ES6语法情况,在ES6语法中我们使用 constructor函数来代替 getInitialState 函数,而getDefaultProps则可以通过手动赋值指定props属性,但已不属于函数方法了。(来源官方文档不适用ES6),但是考虑到可能还有些人依旧会使用ES5语法,这里也会简单介绍这两个函数。(后续若非特别指明,否则讨论范围都在ES6语法之内)
同时在图一,我们可以得知在constructor之后,render之前会有一个getDerivedStateFromProps函数,这个函数在挂载和更新阶段都有可能调用,我们放在update部分来讲。
所以下文我将介绍上述6个函数,包括函数的作用,方法和一些注意事项。
2.1.1 constructor
这是目前常用的一个函数,我们编写的React 类组件都是React.Component基类的继承,组件进行实例化的时候,都会调用其构造函数;如果你不初始化 state,不绑定方法的话,你不需要为 React 组件实现构造函数(它会调用默认构造函数)。
而且在构造函数的开头,你需要调用 super(props), 不然会有许多蜜汁bug难以定义和识别;
通常构造函数的作用就是:
- 初始化内部
state变量 - 为事件处理函数绑定实例
需要注意的时,在构造函数里不要出现setState方法,我们仅需要为this.state赋初始值即可。
一个常见的例子如下:
// credit to https://react.docschina.org/docs/react-component.html#constructor
constructor(props) {
super(props);
// 不要在这里调用 this.setState()
this.state = {
counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
2.1.2 getDefaultProps
这种方法其实只有在使用非ES6语法定义组件(即采用ES5语法 React.createClass定义组件)的时候才会出现,这是一种声明默认组件属性(props)的方法。该函数只会调用一次。
一个简单的例子:
// credit to https://www.cnblogs.com/MuYunyun/p/6629096.html#_lab2_0_0
var MyTitle = React.createClass({
getDefaultProps : function () {
return {
title : 'Hello World' // 声明默认的属性title
};
},
render: function() {
return <h1> {
this.props.title} </h1>; // 调用props属性
}
});
ReactDOM.render(
<MyTitle />,
document.body
);
而在ES6语法中,这个函数已经被弃用了,起同样作用的写法如下:
// credit to
// https://zh-hans.reactjs.org/docs/react-without-es6.html#setting-the-initial-state
class Greeting extends React.Component {
// ...
}
Greeting.defaultProps = {
name: 'Mary'
};
2.1.3 getInitialState
在ES5语法中,这个函数的作用相当于初始化每个组件实例的state变量;在ES6语法中,我们可以通过在constructor函数里头对this.state赋初始值,以起到同样的效果。
getInitialState和getDefaultProps的区别在于,getDefauProps 对于组件类来说只会调用一次,而getInitalState是在每个组件实例化的时候都会调用,并且只调用一次。而props和state的区别在于props是通过父组件传递,在所有实例中共享,而state只存在组件内部,保存组件的某些状态。
这里提供一个代码实例帮助理解:
var LikeButton = React.createClass({
getInitialState: function() {
return {
liked: false};
},
handleClick: function(event) {
this.setState({
liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<p onClick={
this.handleClick}>
You {
text} this. Click to toggle.
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('examp

本文详细介绍了React组件的生命周期,包括挂载、更新和卸载阶段的API,强调了如何使用`useEffect` Hook来替代传统的生命周期方法。在React v16.8版本中,`useEffect`的引入改变了函数组件的游戏规则,允许在函数组件中实现类组件的生命周期功能。文章还提供了一些高质量的React Hooks相关阅读资源。
最低0.47元/天 解锁文章
763

被折叠的 条评论
为什么被折叠?



