博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React入门0x007: 生命周期概念
阅读量:6291 次
发布时间:2019-06-22

本文共 5006 字,大约阅读时间需要 16 分钟。

0x000 概述

上一章只是稍微了解了一下statesetState相关的简单用法,这一章需要讲一下组件的生命周期。

0x001 生命周期的概念

这玩意似乎很高大上,其实就是一个假概念罢了,直接来实现一个类似的吧。大凡事物从出现到消亡都有个过程,而这个过程大抵可以分为:

出现->变化->消亡

web开发中,组件也有类似的过程,当然作为组件的创造者,我们可以干预这个过程,在每个过程加入自己的行为,也就是hook这个过程:

(出现之前)->出现->(出现之后)                     ↓->(循环)[(变化之前)->变化->(变化之后)]                    ↓->      (消亡之前)->消亡->(消亡之后)

这个就是生命周期了,转化成组件:

(组件声明->构造组件->组件挂载之前)->组件挂载->(组件挂载之后)                                   ↓->          (循环)[(组件更新之前)->组件更新->(组件更新之后)]                                   ↓->               (组件卸载之前)->组件卸载->(组件卸载之后)

上面(...)中的便是我们的hook,接下来我们来实现它

0x002 初始化框架

  1. 复制项目

    $ cp 006-state 007-life-cycle
  2. 完成框架主文件-ReactLikeDom.js

    $ cd 0x007-life-cycle/src$ vim ReactLike.js// ReactLikeDom.js 模拟 ReactDomclass ReactLikeDom {    static render(component, container) {    }}export default ReactLikeDom
  3. 完成框架主文件-ReactLike.js

    // ReactLike.js 用来模拟 Reactclass ReactLike {    static createElement(type, props) {    }}export default ReactLike
  4. 完成框架主文件-Component.js

    // 用来模拟 React.Componentclass Component {}export default Component
  5. 完成框架主文件-ReactLikeNode.js

    // 用来模拟 React Element ,每一个组件都将会被抽象成一个 ReatLikeElementclass ReactLikeElement {    constructor() {    }}export default ReactLikeElement
  6. 当前项目文件

    + 0x007-life-cycle+ src    - Component.js    - index.html    - index.js    - ReactLike.js    - ReactLikeDom.js    - ReactLikeElement.js- .babelrc- package.json- webpack.config.js

0x003 我们先看看我们想要干什么

// index.jsimport ReactLikeDom from "./ReactLikeDom";import ReactLike from "./ReactLike";import Component from "./Component";// 声明一个组件class App extends Component {    render() {        return "hello " + this.props.name    }}// 将组件挂载到容器中ReactLikeDom.render(    ReactLike.createElement(App, {name: "reactLike"}, null),    document.getElementById('app'))

打开浏览器查询最终的效果:

clipboard.png

0x004 完成Compoennt.js

这个类其实没有太多需要做的,只是为了继承而已,
而在
React中每一个组件都必须有一个
render方法,该方法返回一个
React Element
而这个方法实在具体的组件完成的,而不是在这里完成,所以我们这里声明一下就好了
class Component {    render() {            }}export default Component

0x004 完成ReactLike

该类有一个方法:
createElement,作用是将一个类组件转化成
ReactLikeElement
import ReactLikeElement from "./ReactLikeElement";class ReactLike {    static createElement(type, props) {        // 直接创建一个 ReactLikeElement 并返回, 具体的实现由 ReactLikeElement 自己完成        return new ReactLikeElement(type, props)    }}export default ReactLike

0x005 完成ReactLikeElement

该类的所有事物都在构造器中完成
class ReactLikeElement {    constructor(type, props) {        // 实例化组件        let component = new type(props)        // 将 props 赋予 该组件实例        component.props = props        // 将该组件的真实 dom 保存在 ref 中        this.ref = component.render()    }}export default ReactLikeElement

0x006 自定义一个组件

// index.jsclass App extends Component {    render() {        let div = document.createElement('div')        div.append("hello " + this.props.name)        return div    }}

该组件返回一个divdiv中包含一个字符串,该字符串的构成是hello 和这个组件的props中的name构成,我们期望外部传入一个name属性。

可以使用该自定义组件测试一下ReactLikeElement,看看一个组件究竟会被转化成什么样:

console.log(new ReactLikeElement(App, {name: "reactLike"}))

查看浏览器

clipboard.png

0x007 完成ReactDom,将该组件挂载到容器中

class ReactLikeDom {    static render(reactLikeElement, container) {        container.append(reactLikeElement.ref)    }}export default ReactLikeDom

ReactLikeDom.render接受一个元素和一个容器,组件是ReactLikeElement,容器是dom,这个方法会将组件挂载到容器上。

这个时候整个流程就已经完成了,查看浏览器

clipboard.png

我们梳理一下整个流程:

// index.jsclass App extends Component {    // 该方法返回一个`dom`,构建这个`dom`用到了`props`中的属性`name`    render() {        let div = document.createElement('div')        div.append("hello " + this.props.name)        return div    }}/* * ReactLikeDom.render 可以将一个`ReactLikeElement`挂载到容器上 * 而 ReactLike.createElement 正好可以创建一个`ReactLikeElement` * 在 ReactLike.createElement 中会构造一个 App 实例 * 然后将 props 传递给该 App 实例 * 然后调用 App.render * 这时候 render 中便可以访问 props 中的属性了 * 接着将 App.render 返回的 dom 保存在 ref 变量中 * ReactLikeDom.render 其实是把 ref 中的 dom 挂载到 容器上 */ReactLikeDom.render(    ReactLike.createElement(App, {name: "react"}, null),    document.getElementById('app'))

0x008 实现生命周期

Component中添加两个方法,代表其中两个生命周期

class Component {    componentWillMount() {    }    componentDidMount() {    }    render() {    }}export default Component

然后在App组件中实现它:

class App extends Component {    componentDidMount() {        console.log('componentDidMount')    }    componentWillMount() {        console.log('componentWillMount')    }    render() {        let div = document.createElement('div')        div.append("hello " + this.props.name)        return div    }}

接着让他起作用:

// ReactLikeDom.jsclass ReactLikeDom {    static render(reactLikeElement, container) {        reactLikeElement.componentWillMount()        container.append(reactLikeElement.ref)        reactLikeElement.componentDidMount()    }}export default ReactLikeDom// ReactLikeElementclass ReactLikeElement {    constructor(type, props) {        let component = new type(props)        component.props = props        this.ref = component.render()        this.component = component // 新添加一个属性    }}export default ReactLikeElement

查看浏览器

clipboard.png

0x009 总结

我们已经实现了其中两个生命周期,其他的声明周期也是如此类似的实现,只是插入的位置和时期不同而已,也造成在每个阶段我们所能访问的资源也不同。

0x010 资源

转载地址:http://crkta.baihongyu.com/

你可能感兴趣的文章
线程管理(六)等待线程的终结
查看>>
spring boot集成mongodb最简单版
查看>>
DELL EqualLogic PS存储数据恢复全过程整理
查看>>
《Node.js入门经典》一2.3 安装模块
查看>>
《Java 开发从入门到精通》—— 2.5 技术解惑
查看>>
Linux 性能诊断 perf使用指南
查看>>
实操分享:看看小白我如何第一次搭建阿里云windows服务器(Tomcat+Mysql)
查看>>
Sphinx 配置文件说明
查看>>
数据结构实践——顺序表应用
查看>>
python2.7 之centos7 安装 pip, Scrapy
查看>>
机智云开源框架初始化顺序
查看>>
Spark修炼之道(进阶篇)——Spark入门到精通:第五节 Spark编程模型(二)
查看>>
一线架构师实践指南:云时代下双活零切换的七大关键点
查看>>
ART世界探险(19) - 优化编译器的编译流程
查看>>
玩转Edas应用部署
查看>>
music-音符与常用记号
查看>>
sql操作命令
查看>>
zip 数据压缩
查看>>
Python爬虫学习系列教程
查看>>
【数据库优化专题】MySQL视图优化(二)
查看>>