React之React渲染原理

一、react如何将代码显示到页面上

每当我们新建react项目时,项目创建成功后,运行npm start后会出现如下界面:
在这里插入图片描述
可以观察到时app.js中对该页面进行的设计,代码如下:
在这里插入图片描述
观察index.js发现最终代码是在这里执行的:
在这里插入图片描述
React将代码显示出来主要有两个步骤:

  1. JSX转化为Element
  2. Element转化为Dom

(1)JSX生成Element

1. JSX语法

可以看到第一个张图片中的render函数中return了一段html片段,这段片段就是JSX语法

定义:JSX 即Javascript XML,它是对JavaScript 语法扩展。React 使用 JSX 来替代常规的 JavaScript。你也可以认为JSX其实就是JavaScript。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析。

优点
执行速度更快,因为它在编译为JavaScript代码后进行了优化

2. 使用babel对JSX语法进行转换

return (
    <div className="cn">
         <Header> Hello, This is React </Header>
         <div>Start to learn right now!</div>
         Right Reserve.
    </div>
)

通过babel编译成React.createElement的表达式。

return (
    React.createElement(
        'div',
        { className: 'cn' },
        React.createElement(
            Header,
            null,
            'Hello, This is React'
        ),
        React.createElement(
            'div',
            null,
            'Start to learn right now!'
        ),
        'Right Reserve'
    )
)

当render函数被调用时,会执行React.createElement的表达式,返回Element元素

3. 创建虚拟Dom

调用React.createElement方法时,React 把真实的 DOM 树转换成 Javascript 对象树,会创建虚拟Dom树,也就是 Virtual Dom。

每次数据更新后,重新计算 Virtual Dom ,并和上一次生成的 virtual dom 做对比,对发生变化的部分做批量更新。

而 React 是通过创建与更新虚拟元素 Virtual Element 来管理整个Virtual Dom 的。


虚拟元素可以理解为真实元素的对应,它的构建与更新都是在内存中完成的,并不会真正渲染到 dom 中去。

虚拟dom 实际上是对实际Dom的一个抽象,是一个js对象。
react所有的表层操作实际上是在操作Virtual dom。

(2)Element生成Dom

上一步通过JSX获得了虚拟Dom树,现在需要将虚拟Dom转化为真实的Dom,可以看到第二张图里的ReactDOM.render 方法。

这时可以利用 ReactDOM.render 方法,传入一个 reactElement 和一个 作为容器的 DOM 节点。

而这个方法查看到源码可以看见是调用了一个instantiateReactComponent函数,这个函数 创建了一个ReactComponent 的实例并返回,也可以看到 ReactDOM.render 最后返回的也是这个实例。
代码如下:

    function instantiateReactComponent(node) {
      var instance;
    
      if (node === null || node === false) {
        instance = new ReactEmptyComponent(instantiateReactComponent);----------(1)
      } else if (typeof node === 'object') {
        var element = node;
        '
          如果 type的类型是string 则说明它是 普通的HTML标签,那么直接按照普通的方式生成 DOM
          
          而如果不是string的话,比如是
          ƒ ()  ƒ App(props)之类的,则说明他们是 自定义的组件。
          则要另行处理。
        '
        
        if (typeof element.type === 'string') {
            '
            ReactNativeComponent.createInternalComponent 方法是被注入进来的,注入的是 ReactDOMComponent 类。
            最终的结构是 new ReactDOMComponent(element.type,element.props)
    
            生成一个 ReactDOMComponent 的实例返回
            '
            
          instance = ReactNativeComponent.createInternalComponent(element);--------(2)
        } else if (isInternalComponentType(element.type)) {
          instance = new element.type(element);---------------(3)
        } else {
    
            '
            是我们自定义的类的时候 执行该方法来进行生成 instance 操作。
            '
          instance = new ReactCompositeComponentWrapper();----------(4)
          
        }
      } else if (typeof node === 'string' || typeof node === 'number') {
        instance = ReactNativeComponent.createInstanceForText(node);----------(5)
      } else {
        !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : invariant(false) : undefined;
      }
    
     
      instance.construct(node);
    
     
      instance._mountIndex = 0;
      instance._mountImage = null;
    
      return instance;
    }

instantiateReactComponent 方法是初始化组件的入口函数,它通过判断 node 的类型来创建不同的react对象。

  • 当 node 为空的时候,初始化组件。
  • 当 node 为对象,类型 type 字段标记为是字符串,初始化 DOM 标签。否则初始化自定义组件。
  • 当 node 为字符串或者数字时,初始化文本组件。

创建了 Component 实例后,调用 component 的 mountComponent 方法,注意到这里是会被批量 mount 的,然后就可以进行渲染。

参考文章:https://cloud.tencent.com/developer/article/1520009

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值