react 是怎么运行的?
react 是怎么运行的?
import React from 'react';
import ReactDOM from 'react-dom';const App = <div className="title" style={{color:'red'}}>hello world</div>
console.log('App', App)ReactDOM.render(App,document.getElementById('root')
);
react 运行的主要3阶段:
1. jsx 转成 js 代码
由于 js 不认识 jsx 代码,所以需要将下面 jsx 语法转化成 js 代码
<div className="title" style={{color:'red'}}>hello world</div>
点击此 jsx to react 复制上述代码进去即可转化成 js 代码, 代码如下:
React.createElement("div", {className: "title",style: {color: 'red'}
}, "hello world");
在 create-react-app 项目中,我们通过 react-scripts start
可以运行 react 项目是因为 react-scripts 将 jsx 转化成了 js 代码。
2. js 代码生成 vdom
现在知道为什么没有使用 react 都需要 import React from 'react';
引入了吧, 因为 jsx 转 js 后的代码会用到 react。
执行如下方法会生成什么呢?
React.createElement("div", {className: "title",style: {color: 'red'}
}, "hello world");
会生成如下对象:
{'$$typeof': Symbol(react.element), // 标记是 react 节点type: 'div', // 标签类型key: null,ref: null,props: { // 标签的属性className: 'title',style: { color: 'red' },children: 'hello world'}
}
该对象就是通过 js 对象的形式描述了一个 html 节点,也就是所谓的 vdom (虚拟dom), 后续 diff 算法就是直接给它进行对比更新dom
3. vdom 转化成 dom 挂载到 #root
ReactDOM.render({'$$typeof': Symbol(react.element), // 标记是 react 节点type: 'div', // 标签类型key: null,ref: null,props: { // 标签的属性className: 'title',style: { color: 'red' },children: 'hello world'}},document.getElementById('root')
);
ReactDOM.render 内部主要执行过程如下:
function render(vdom, container) {let newDOM = createDOM(vdom); // 对象转 domcontainer.appendChild(newDOM); // 生成的节点挂载到 root 节点里面
}function createDOM(vdom) {let { type, props } = vdom;let dom;if (type === REACT_TEXT) {dom = document.createTextNode(props.content);} else {dom = document.createElement(type);}if (props) {updateProps(dom, {}, props);if (typeof props.children == "object" && props.children.type) {mount(props.children, dom);} else if (Array.isArray(props.children)) {reconcileChildren(props.children, dom);}}vdom.dom = dom;return dom;
}
function updateProps(dom, oldProps={}, newProps={}) {for (let key in newProps) {if (key === 'children') {continue;} else if (key === 'style') {let styleObj = newProps[key];for (let attr in styleObj) {dom.style[attr] = styleObj[attr];}}else {dom[key] = newProps[key];}}for(let key in oldProps){if(!newProps.hasOwnProperty(key)){dom[key] = null;}}
}
function reconcileChildren(childrenVdom, parentDOM) {for (let i = 0; i < childrenVdom.length; i++) {let childVdom = childrenVdom[i];mount(childVdom, parentDOM);}
}const ReactDOM = { render };
此时打开浏览器我们就看见了 hello world
本系列代码 | 链接 |
---|---|
GitHub | https://github.com/shunyue1320/mini-react/tree/react-01 |
Gitee | https://gitee.com/shunyue/mini-react/tree/react-01/ |
react 是怎么运行的?相关推荐
- Taro3.2 适配 React Native 之运行时架构详解
导读 由 58 前端团队主导的 Taro 3 适配 React Native 工作已完成有一段时间了.目前发布了多个体验版,也将在3月底迎来正式版.基于 Taro 的良好架构演变,适配 React N ...
- React、react生命周期、react生命周期运行过程、shouldComponentUpdate的用法
React.react生命周期.react生命周期运行过程 1.创建阶段 constructor(){super()console.log('执行构造函数')this.state={num:1}}UN ...
- 配置React项目的运行环境
两种配置react项目运行环境的方法 第一种方法,一步步配置项目的运行环境: 1)下载node,在官方网站可以下载,安装步骤不难,差不多一步步意 点next就行: 2)运行cmd 输入node -v ...
- react项目如何运行
入门react时,最烦的就是配置各种依赖,不管是你从网上down的别人的代码还是你自己的代码换个工作目录运行,都会发现运行不起来. 解决办法是,移动react项目时不要把node_modules一同复 ...
- React引入,运行
1.引入 <script src="https://cdn.bootcss.com/react/15.5.4/react.min.js"></script> ...
- React P68 npm运行脚手架启动项目后显示‘无法访问此网站’
将代码: const proxy = require('http-proxy-middleware')module.exports = function(app){app.use(proxy('/ap ...
- 如何在iOS上运行React Native应用
by Soujanya PS 通过Soujanya PS 如何在iOS上运行React Native应用 (How to run a React Native app on iOS) I recent ...
- React Native运行原理解析
Facebook 于2015年9月15日推出react native for Android 版本, 加上2014年底已经开源的IOS版本,至此RN (react-native)真正成为跨平台的客户端 ...
- 解决react脚手架运行后多出来很多webpack的日志
我理想中的react脚手架本地运行后的结果是这样的: 但是在新的Windows笔记本用create-react-app创建react项目启动后是这样的: 这种结果的我个人感觉的缺点就是: 覆盖了项目l ...
最新文章
- 盛大文学难逃“垄断”嫌疑,完美文学虎口夺食
- maven私有库搭建
- WIN10系统上,新建AliOS Things项目
- ASP.NET 页生命周期概述
- 怎么样才能让自己自律起来_一个人如何才能高度自律(深度好文)
- 【毕业求职季】-听说你想去大厂看学妹,带你看看腾讯微信产品岗面经(已offer)
- C++:常用数据类型及常见操作
- awk用法:取列表最后一列
- (3.2)HarmonyOS鸿蒙双击事件
- Node.js--Stream
- 迭代器 iterator
- 小米笔记本air13-3安装黑苹果macOS
- 数字电路设计:竞争冒险以及消除方法
- lzg_ad:XPE系统管理工具组件
- CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark
- [java] JavaMail发送邮件
- 安全帽图像识别python_基于opencv的安全帽佩戴检测
- 在线电子书阅读微信小程序 毕业设计(2)分类
- JAVA(第六版)——期末复习2
- STL容器基础 - 0