资讯专栏INFORMATION COLUMN

React入门0x007: 生命周期概念

Blackjun / 1343人阅读

摘要:概述上一章只是稍微了解了一下和相关的简单用法,这一章需要讲一下组件的生命周期。生命周期的概念这玩意似乎很高大上,其实就是一个假概念罢了,直接来实现一个类似的吧。

0x000 概述

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

0x001 生命周期的概念

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

出现->变化->消亡

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

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

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

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

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

0x002 初始化框架

复制项目

$ cp 006-state 007-life-cycle

完成框架主文件-ReactLikeDom.js

$ cd 0x007-life-cycle/src
$ vim ReactLike.js
// ReactLikeDom.js 模拟 ReactDom
class ReactLikeDom {
    static render(component, container) {
    }
}
export default ReactLikeDom   

完成框架主文件-ReactLike.js

// ReactLike.js 用来模拟 React
class ReactLike {
    static createElement(type, props) {
    }
}

export default ReactLike

完成框架主文件-Component.js

// 用来模拟 React.Component
class Component {

}
export default Component

完成框架主文件-ReactLikeNode.js

// 用来模拟 React Element ,每一个组件都将会被抽象成一个 ReatLikeElement
class ReactLikeElement {
    constructor() {

    }

}

export default ReactLikeElement

当前项目文件

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

0x003 我们先看看我们想要干什么
// index.js
import 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")
)

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

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.js
class 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"}))

查看浏览器

0x007 完成ReactDom,将该组件挂载到容器中
class ReactLikeDom {
    static render(reactLikeElement, container) {
        container.append(reactLikeElement.ref)
    }

}

export default ReactLikeDom

ReactLikeDom.render接受一个元素和一个容器,组件是ReactLikeElement,容器是dom,这个方法会将组件挂载到容器上。
这个时候整个流程就已经完成了,查看浏览器

我们梳理一下整个流程:

// index.js
class 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.js
class ReactLikeDom {
    static render(reactLikeElement, container) {
        reactLikeElement.componentWillMount()
        container.append(reactLikeElement.ref)
        reactLikeElement.componentDidMount()
    }

}

export default ReactLikeDom

// ReactLikeElement
class ReactLikeElement {
    constructor(type, props) {
        let component = new type(props)
        component.props = props
        this.ref = component.render()
        this.component = component // 新添加一个属性
    }

}

export default ReactLikeElement

查看浏览器

0x009 总结

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

0x010 资源

react

transform-react-jsx

源码

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97058.html

相关文章

  • React入门0x008: 生命周期

    0x000 概述 上一章说明了生命周期的概念,本质上就是框架在操作组件的过程中暴露出来的一系列钩子,我们可以选择我们需要的钩子,完成我们自己的业务,以下讲的是react v16.3以下的生命周期,v16.3以及以上的版本有所不同 0x001 组件挂载 以下是组件挂载的过程中触发的声明周期: class App extends React.Component { constructor(pr...

    loonggg 评论0 收藏0
  • Router入门0x201: 从 URL 到 SPA

    摘要:的全称是统一资源定位符英文,可以这么说,是一种标准,而网址则是符合标准的一种实现而已。渲染器,将组件渲染到页面上。 0x000 概述 从这一章开始就进入路由章节了,并不直接从如何使用react-route来讲,而是从路由的概念和实现来讲,达到知道路由的本质,而不是只知道如何使用react-route库的目的,毕竟react-route只是一个库,是路由的一个实现而已,而不是路由本身。 ...

    honmaple 评论0 收藏0
  • 快速入门React

    摘要:考虑到是快速入门,于是乎我们就记住一点,当修改值需要重新渲染的时候,的机制是不会让他全部重新渲染的,它只会把你修改值所在的重新更新。这一生命周期返回的任何值将会作为参数被传递给。 安装react npm install creat-react-app -gshowImg(https://segmentfault.com/img/remote/1460000015639868); 这里直...

    figofuture 评论0 收藏0
  • 我的React之路--入门

    摘要:在构造函数里面初始化的数据,把数据放在页面上,点击时候调用方法改变中的数据。是中父组件向子组件通信的方式,下面是一个简单的例子使用组件我是显示的数据我们定义组件时候在构造函数中可以接收到参数,并且要使用传到的构造方法中。 React的学习之路还要继续走下去,最近一边在做未完成的项目一边学习React,项目是vue写的,后面还需要有一个后台管理系统计划使用react完成,寒假说长也不长,...

    qpwoeiru96 评论0 收藏0
  • 写一本关于 React.js 的小书

    摘要:因为工作中一直在使用,也一直以来想总结一下自己关于的一些知识经验。于是把一些想法慢慢整理书写下来,做成一本开源免费专业简单的入门级别的小书,提供给社区。本书的后续可能会做成视频版本,敬请期待。本作品采用署名禁止演绎国际许可协议进行许可 React.js 小书 本文作者:胡子大哈本文原文:React.js 小书 转载请注明出处,保留原文链接以及作者信息 在线阅读:http://huzi...

    Scorpion 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<