每当我们新建react项目时,项目创建成功后,运行npm start后会出现如下界面: 可以观察到时app.js中对该页面进行的设计,代码如下: 观察index.js发现最终代码是在这里执行的: React将代码显示出来主要有两个步骤:
JSX转化为ElementElement转化为Dom可以看到第一个张图片中的render函数中return了一段html片段,这段片段就是JSX语法
定义:JSX 即Javascript XML,它是对JavaScript 语法扩展。React 使用 JSX 来替代常规的 JavaScript。你也可以认为JSX其实就是JavaScript。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析。
优点: 执行速度更快,因为它在编译为JavaScript代码后进行了优化
通过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元素
调用React.createElement方法时,React 把真实的 DOM 树转换成 Javascript 对象树,会创建虚拟Dom树,也就是 Virtual Dom。
每次数据更新后,重新计算 Virtual Dom ,并和上一次生成的 virtual dom 做对比,对发生变化的部分做批量更新。
而 React 是通过创建与更新虚拟元素 Virtual Element 来管理整个Virtual Dom 的。
虚拟元素可以理解为真实元素的对应,它的构建与更新都是在内存中完成的,并不会真正渲染到 dom 中去。
虚拟dom 实际上是对实际Dom的一个抽象,是一个js对象。 react所有的表层操作实际上是在操作Virtual 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