我们在讲解 JSX 的章节中提到,下面的代码:

ReactDOM.render(
<Header />,
document.getElementById('root')
)

会编译成:

ReactDOM.render(
React.createElement(Header, null),
document.getElementById('root')
)

其实我们把 Header 组件传给了 React.createElement 函数,又把函数返回结果传给了 ReactDOM.render。我们可以简单猜想一下它们会干什么事情:

// React.createElement 中实例化一个 Header
const header = new Header(props, children)
// React.createElement 中调用 header.render 方法渲染组件的内容
const headerJsxObject = header.render() // ReactDOM 用渲染后的 JavaScript 对象来来构建真正的 DOM 元素
const headerDOM = createDOMFromObject(headerJsxObject)
// ReactDOM 把 DOM 元素塞到页面上
document.getElementById('root').appendChild(headerDOM)

上面过程其实很简单,看代码就能理解。

我们把 React.js 将组件渲染,并且构造 DOM 元素然后塞入页面的过程称为组件的挂载(这个定义请好好记住)。其实 React.js 内部对待每个组件都有这么一个过程,也就是初始化组件 -> 挂载到页面上的过程。所以你可以理解一个组件的方法调用是这么一个过程:

-> constructor()
-> render()
// 然后构造 DOM 元素插入页面

这当然是很好理解的。React.js 为了让我们能够更好的掌控组件的挂载过程,往上面插入了两个方法:

-> constructor()
-> componentWillMount()
-> render()
// 然后构造 DOM 元素插入页面
-> componentDidMount()

componentWillMount 和 componentDidMount 都是可以像 render 方法一样自定义在组件的内部。挂载的时候,React.js 会在组件的 render 之前调用 componentWillMount,在 DOM 元素塞入页面以后调用 componentDidMount

我们给 Header 组件加上这两个方法,并且打一些 Log:

class Header extends Component {
constructor () {
super()
console.log('construct')
} componentWillMount () {
console.log('component will mount')
} componentDidMount () {
console.log('component did mount')
} render () {
console.log('render')
return (
<div>
<h1 className='title'>React 小书</h1>
</div>
)
}
}

在控制台你可以看到依次输出:

可以看到,React.js 确实按照我们上面所说的那样调用了定义的两个方法 componentWillMount 和 componentDidMount

机灵的同学可以想到,一个组件可以插入页面,当然也可以从页面中删除。

-> constructor()
-> componentWillMount()
-> render()
// 然后构造 DOM 元素插入页面
-> componentDidMount()
// ...
// 从页面中删除

React.js 也控制了这个组件的删除过程。在组件删除之前 React.js 会调用组件定义的 componentWillUnmount

-> constructor()
-> componentWillMount()
-> render()
// 然后构造 DOM 元素插入页面
-> componentDidMount()
// ...
// 即将从页面中删除
-> componentWillUnmount()
// 从页面中删除

看看什么情况下会把组件从页面中删除,继续使用上面例子的代码,我们再定义一个 Index 组件:

class Index extends Component {
constructor() {
super()
this.state = {
isShowHeader: true
}
} handleShowOrHide () {
this.setState({
isShowHeader: !this.state.isShowHeader
})
} render () {
return (
<div>
{this.state.isShowHeader ? <Header /> : null}
<button onClick={this.handleShowOrHide.bind(this)}>
显示或者隐藏标题
</button>
</div>
)
}
} ReactDOM.render(
<Index />,
document.getElementById('root')
)

Index 组件使用了 Header 组件,并且有一个按钮,可以控制 Header 的显示或者隐藏。下面这行代码:

...a
{this.state.isShowHeader ? <Header /> : null}
...

相当于 state.isShowHeader 为 true 的时候把 Header 插入页面,false 的时候把 Header 从页面上删除。这时候我们给 Header 添加 componentWillUnmount 方法:

...
componentWillUnmount() {
console.log('component will unmount')
}
...

这时候点击页面上的按钮,你会看到页面的标题隐藏了,并且控制台打印出来下图的最后一行,说明 componentWillUnmount 确实被 React.js 所调用了:

你可以多次点击按钮,随着按钮的显示和隐藏,上面的内容会按顺序重复地打印出来,可以体会一下这几个方法的调用过程和顺序。

总结

React.js 将组件渲染,并且构造 DOM 元素然后塞入页面的过程称为组件的挂载。这一节我们学习了 React.js 控制组件在页面上挂载和删除过程里面几个方法:

  • componentWillMount:组件挂载开始之前,也就是在组件调用 render 方法之前调用。
  • componentDidMount:组件挂载完成以后,也就是 DOM 元素已经插入页面后调用。
  • componentWillUnmount:组件对应的 DOM 元素从页面中删除之前调用。

但这一节并没有讲这几个方法到底在实际项目当中有什么作用,下一节我们通过例子来讲解一下这几个方法的用途。


因为第三方评论工具有问题,对本章节有任何疑问的朋友可以移步到 React.js 小书的论坛 发帖,我会回答大家的疑问。

React.js 小书 Lesson18 - 挂载阶段的组件生命周期(一)的更多相关文章

  1. React.js 小书 Lesson19 - 挂载阶段的组件生命周期(二)

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson19 转载请注明出处,保留原文链接和作者信息. 这一节我们来讨论一下对于一个组件来说,cons ...

  2. React.js 小书 Lesson20 - 更新阶段的组件生命周期

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson20 转载请注明出处,保留原文链接和作者信息. 从之前的章节我们了解到,组件的挂载指的是将组件 ...

  3. 【React.js小书】动手实现 React-redux(五):Provider - 方志

    我们要把 context 相关的代码从所有业务组件中清除出去,现在的代码里面还有一个地方是被污染的.那就是 src/index.js 里面的 Index: 1234567891011121314151 ...

  4. React.js 小书介绍

    React.js 小书 Github 关于作者 这是一本关于 React.js 的小书. 因为工作中一直在使用 React.js,也一直以来想总结一下自己关于 React.js 的一些知识.经验.于是 ...

  5. React.js 小书 Lesson16 - 实战分析:评论功能(三)

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson16 转载请注明出处,保留原文链接和作者信息. 接下来的代码比较顺理成章了.修改 Commen ...

  6. React.js小书总结

    (迁移自旧博客2017 08 27) 第一阶段 react的组件相当于MVC里面的View. react.js 将帮助我们将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合.嵌套,就成 ...

  7. React.js 小书 Lesson25 - 实战分析:评论功能(四)

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson25 转载请注明出处,保留原文链接和作者信息. (本文未审核) 目前为止,第二阶段知识已经基本 ...

  8. React.js 小书 Lesson26 - 实战分析:评论功能(五)

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson26 转载请注明出处,保留原文链接和作者信息. (本文未审核) 持久化评论 同样地,可以通过类 ...

  9. React.js 小书 Lesson24 - PropTypes 和组件参数验证

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson24 转载请注明出处,保留原文链接和作者信息. 我们来了到了一个非常尴尬的章节,很多初学的朋友 ...

随机推荐

  1. U盘安装Ubuntu 12.04成功后系统无法启动的原因及解决办法

    想搭建一个Linux开发环境,选择了ubuntu12.04长期支持版,采用u盘安装(Universal-USB-Installer做的启动),发现安装完成之后,拔掉u盘无法启动,插上u盘之后,可以重启 ...

  2. .net core MVC 通过 Filters 过滤器拦截请求及响应内容

    前提: 需要nuget   Microsoft.Extensions.Logging.Log4Net.AspNetCore   2.2.6: Swashbuckle.AspNetCore 我暂时用的是 ...

  3. NSKeyedArchiver数据归档

    前言 在 OC 语言中,归档是一个过程,即用某种格式来保存一个或多个对象,以便以后还原这些对象. 通常,这个过程包括将(多个)对象写入文件中,以便以后读取该对象.可以使用归档的方法进行对象的深复制. ...

  4. IIS发布ASP程序问题汇总

    看异常位置,因为域的问题

  5. yunpian-python-sdk

    快速开始 安装SDK pip install yunpian-python-sdk 代码 使用YunpianClient from yunpian_python_sdk.model import co ...

  6. MySQL 学习笔记(二):数据库更新、视图和数据控制

    基础准备: 在 school 数据库下建立student.course.sc 三个表: create table student( Sno ) primary key, Sname ) unique, ...

  7. bzoj1565【NOI2009】植物大战僵尸(最小割)

    题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...

  8. adminlte+layui框架搭建1

    之前写过一篇layui-master的UI搭建,但是感觉layui-master缺少一些东西(前台页面不过多研究),比如说页面的皮肤.菜单.插件,当然我也希望layui的插件可以越来越多,支持多个浏览 ...

  9. bzoj1087 互不侵犯King 状压dp+bitset

    题目传送门 题目大意:中文题面. 思路:又是格子,n又只有9,所以肯定是状压dp,很明显上面一行的摆放位置会影响下一行,所以先预处理出怎样的二进制摆放法可以放在上下相邻的两行,这里推荐使用bitset ...

  10. 马的移动(BFS) 详细注释 一个具有情怀的题目

    题目描述 小明很喜欢下国际象棋,一天,他拿着国际象棋中的"马"时突然想到一个问题: 给定两个棋盘上的方格a和b,马从a跳到b最少需要多少步? 现请你编程解决这个问题. 提示:国际象 ...