什么是 React
React是一个简单的javascript UI库,用于构建高效、快速的用户界面。它是一个轻量级库,因此很受欢迎。它遵循组件设计模式、声明式编程范式和函数式编程概念,以使前端应用程序更高效。它使用虚拟DOM来有效地操作DOM。它遵循从高阶组件到低阶组件的单向数据流。
前言
我们认为,React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方式。它在 Facebook 和 Instagram 上表现优秀。官网地址

react 的理念是在于对大型项目的快速响应,对于新版的 react 16.8 而言更是带来的全新的理念fiber去解决网页快速响应时所伴随的问题,即 CPU 的瓶颈,传统网页浏览受制于浏览器刷新率、js 执行时间过长等因素会造成页面掉帧,甚至卡顿
react 由于自身的底层设计从而规避这一问题的发生,所以 react16.8 的面世对于前端领域只办三件事:快速响应、快速响应、还是 Tmd 快速响应 !,这篇文章将会从一个 html 出发,跟随 react 的 fiber 理念,仿一个非常基础的 react
一开始的准备工作
html
我们需要一个 html 去撑起来整个页面,支撑 react 运行,页面中添加<div></div>,之后添加一个 script 标签,因为需要使用import进行模块化构建,所以需要为 script 添加 type 为module的属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="root"></div> <script type="module" src="./index.js" ></script> </body> </html>
推荐安装一个 Live Server 插件,有助于我们对代码进行调试,接下来的操作也会用到
JavaScript
我们会仿写一个如下的 react,实现一个基础的操作,在 <input/> 绑定事件,将输入的值插入在 <h2/> 标签内:
...
function App() {
return (
<div>
<input onInput={updateValue} value={value} />
<h2>Hello {value}</h2>
<hr />
</div>
);
}
...

在 react 进行 babel 编译的时候,会将 JSX 语法转化为 React.createElement() 的形式,如上被 retuen 的代码就会被转换成
...
React.createElement(
"div",
null,
React.createElement("input", {
onInput: updateValue,
value: value,
}),
React.createElement("h2", null, "Hello ", value),
React.createElement("hr", null)
);
...
在线地址
从转换后的代码我们可以看出 React.createElement 支持多个参数:
type,节点类型 config, 节点上的属性,比如 id 和 href children, 子元素了,子元素可以有多个,类型可以是简单的文本,也可以还是 React.createElement,如果是 React.createElement,其实就是子节点了,子节点下面还可以有子节点。这样就用 React.createElement 的嵌套关系实现了 HTML 节点的树形结构。
我们可以按照 React.createElement 的形式仿写一个可以实现同样功能的 createElement 将 jsx 通过一种简单的数据结构展示出来即 虚拟DOM 这样在更新时,新旧节点的对比也可以转化为虚拟 DOM 的对比
{
type:'节点标签',
props:{
props:'节点上的属性,包括事件、类...',
children:'节点的子节点'
}
}
这里我们可以写一个函数实现下列需求
原则是将所有的参数返回到一个对象上 children 也要放到 props 里面去,这样我们在组件里面就能通过 props.children 拿到子元素 当子组件是文本节点时,通过构造一种 type 为 TEXT_ELEMENT 的节点类型表示
/**
* 创建虚拟 DOM 结构
* @param {type} 标签名
* @param {props} 属性对象
* @param {children} 子节点
* @return {element} 虚拟 DOM
*/
const createElement = (type, props, ...children) => ({
type,
props: {
...props,
children: children.map(child =>
typeof child === "object"
? child
: {
type: "TEXT_ELEMENT",
props: {
nodeValue: child,
children: [],
},
}
),
},
});
react 中 createElement 源码实现
实现 createElement 之后我们可以拿到虚拟 DOM,但是还需要 render 将代码渲染到页面,此时我们需要对 index.js 进行处理,添加输入事件,将 createElement 和 render 通过 import 进行引入,render 时传入被编译后的虚拟 DOM 和页面的根元素 root, 最后再进行executeRender调用,页面被渲染,在页面更新的时候再次调用executeRender进行更新渲染
import {createElement,render} from "./mini/index.js";
const updateValue = e => executeRender(e.target.value);
const executeRender = (value = "World") => {
const element = createElement(
"div",
null,
createElement("input", {
onInput: updateValue,
value: value,
}),
createElement("h2", null, "Hello ", value),
createElement("hr", null)
);
render(element, document.getElementById("root"));
};
executeRender();

评论(0)