React之React渲染原理

2022-09-27 14:08:41

一、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 最后返回的也是这个实例。
代码如下:

functioninstantiateReactComponent(node){var instance;if(node===null|| node===false){
        instance=newReactEmptyComponent(instantiateReactComponent);----------(1)}elseif(typeof node==='object'){var element= node;
        '
          如果 type的类型是string 则说明它是 普通的HTML标签,那么直接按照普通的方式生成DOM
          
          而如果不是string的话,比如是ƒ()  ƒApp(props)之类的,则说明他们是 自定义的组件。
          则要另行处理。
        'if(typeof element.type==='string'){
            '
            ReactNativeComponent.createInternalComponent 方法是被注入进来的,注入的是 ReactDOMComponent 类。
            最终的结构是newReactDOMComponent(element.type,element.props)
    
            生成一个 ReactDOMComponent 的实例返回
            '
            
          instance= ReactNativeComponent.createInternalComponent(element);--------(2)}elseif(isInternalComponentType(element.type)){
          instance=newelement.type(element);---------------(3)}else{
    
            '
            是我们自定义的类的时候 执行该方法来进行生成 instance 操作。
            '
          instance=newReactCompositeComponentWrapper();----------(4)}}elseif(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

  • 作者:Welkin_qing
  • 原文链接:https://blog.csdn.net/Welkin_qing/article/details/109186322
    更新时间:2022-09-27 14:08:41