React小书学习笔记 —— 挂载阶段的组件生命周期(一)

前言

学习前端一小步,迈向成功一大步!本专栏主要记录学习前端React框架的一些个人心得,分享一些实战教学,如有不足,欢迎交流讨论。React框架的入门教学强推胡子大哈React小书,简单易懂还有代码实战。还等什么?让我们开始本篇的前端学习之旅,欢迎各位入坑前端!

挂载阶段的组件生命周期(一)

参考教程:React小书–第18节(挂载阶段的组件生命周期(一))
教程作者:胡子大哈
参考链接:React小书
本文搭配原文教程食用,风味更佳~!


组件挂载

定义:React.js 将组件渲染,并且构造 DOM 元素然后塞入页面的过程。
回顾前文可知,在每个组件内部render()方法能够实现虚拟DOM元素的构造,而组件真实DOM元素的构造实际上是在ReactDOM.render()方法中实现的。
了解上述知识后对定义做更深入的解释:

  1. 组件渲染:==render(),包括了虚拟DOM元素的构造constructor()和渲染render()
  2. 构造DOM元素并渲染到页面:==ReactDOM.render(),包括了真正DOM元素的渲染。

React.js 内部对待每个组件都有这么一个组件挂载的过程,也就是初始化组件 -> 挂载到页面的过程。具体挂载过程如下:

1
2
3
4
-> constructor() #组件内部的构造函数
-> render() #虚拟DOM渲染
//构造真实 DOM 元素插入页面
-> ReactDOM.render() #构造真正DOM元素渲染到页面

更新:ReactDOM.render() 返回 render() 的 Component 实例,即虚拟DOM的实例,其实就是真实DOM元素。参考

React组件挂载的生命周期

组件挂载时有关的生命周期有以下几个:

  1. constructor()
  2. componentWillMount()
  3. render()
  4. componentDidMount()

此处为什么单独罗列出来呢?因为 constructor(),render()也是组件挂载的生命周期,此处没有理解说明对React生命周期的概念没有理解透彻,不过不着急,可以先进行后面的学习,回头再结合React组件生命周期的总体框架图,你将会恍然大悟,总体框架图后续补充~

componentWillMount & componentDidMount & componentWillUnmount

我们已经知道了 componentWillMount 和 componentDidMount 是组件挂载时的生命周期(还有组件更新的生命周期,此处要区分),他们的作用主要是为了让我们更好的掌握组件的挂载过程,加入了 componentWillMount 和 componentDidMount 后,我们的组件挂载过程就可以表示如下:

1
2
3
4
5
6
-> constructor()
-> componentWillMount()
-> render()
//构造真实 DOM 元素插入页面
-> ReactDOM.render()
-> componentDidMount()

componentWillMount 和 componentDidMount 都是像 render 方法一样自定义在组件内部的,即如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class xxx extends Component {
constructor() {
super()
...
}

componentWillMount() {
...
}

componentDidMount() {
...
}

//每个组件必须实现一个render()方法,render方法必须返回一各JSX元素,return必须带(),必须要用一个外层的 JSX 元素把所有内容包裹起来,返回并列多个 JSX 元素是不合法的。
render() {
...
return (
<div>
JSX
</div>
)
}
}

更新:react 组件的 render 方法,对应上述代码中关于 render 方法注意事项的解释。

挂载的时候,React.js 会在组件的render()之前调用 componentWillMount,在 DOM 元素塞入页面(即ReactDOM.render())以后调用 componentDidMount。

此外,我们既然能控制组件插入页面时的生命周期,那么我们应该也能控制其在页面中删除的生命周期,React.js 实际上也控制了这个组件的删除过程。在组件删除之前 React.js 会调用组件定义的 componentWillUnmount。那么我们的组件挂载生命周期可以写成:

1
2
3
4
5
6
7
8
9
10
-> constructor()
-> componentWillMount()
-> render()
//构造真实 DOM 元素插入页面
-> ReactDOM.render()
-> componentDidMount()
...
// 即将从页面中删除
-> componentWillUnmount()
// 从页面中删除

总结

至此,我们已经简单了解了组件挂载过程的生命周期,本节主要有以下几个重点:

  1. 组件挂载的定义
  2. 什么是组件的生命周期
  3. componentWillMount():组件挂载开始之前,也就是在组件调用 render 方法之前调用。
  4. componentDidMount():组件挂载完成以后,也就是 DOM 元素已经插入页面后调用。
  5. componentWillUnmount():组件对应的 DOM 元素从页面中删除之前调用。

我们需要重点理解的是,组件生命周期调用是有次序的,自上而下分别是 constructor -> componentWillMount -> render -> ReactDOM.render -> componentDidMount -> componentWillUnmount

参考
也就是当说如果你要获取外部数据并加载到组件上,只能在组件”已经”挂载到真实的网页上才能作这事情,其它情况你是加载不到组件的。componentDidMount方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。此外,在这方法中调用setState方法,会触发重渲染。所以,官方设计这个方法就是用来加载外部数据用的,或处理其他的副作用代码。
constructor被调用是在组件准备要挂载的最一开始,所以此时组件尚未挂载到网页上。componentWillMount方法的调用在constructor之后,在render之前,在这方法里的代码调用setState方法不会触发重渲染,所以它一般不会用来作加载数据之用,它也很少被使用到**(componentWillMount无法触发setState重渲染)**。一般的从后台(服务器)获取的数据,都会与组件上要用的数据加载有关,所以都在componentDidMount方法里面作。虽然与组件上的数据无关的加载,也可以在constructor里作,但constructor是作组件state初绐化工作,并不是设计来作加载数据这工作的,所以所有有副作用的代码都会集中在componentDidMount方法里。