写在前面
引入了 React 之后,开始使用 React 做一个小的 demo,即实现一个按钮点击加一,使用 CDN 引入 React,使用在线工具 codesandbox 的原生 JS 项目编写。
1. 引入 React 和 ReactDOM
在 index.html 中使用 BootCDN 引入 React
<script src="https://cdn.bootcss.com/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="src/index.js"></script>
引入后在 index.js 中输出 React 和 ReactDOM 对象看一下,注意:使用 BootCDN 引入的都会变成全局对象,挂在 window 上,因此若无法直接访问到 React,就使用 window.React 访问 React 对象。
console.log(window.React);
2. 使用 React 创建虚拟 DOM
React 有提供 createElement API 接口 ,用于创建页面中需要的 DOM 元素,由于不是使用 DOM 的 API 直接创建一个真实的 DOM 元素,而是依据 React 的语法创建一个 React 元素,再由 React 负责将元素插入到页面中去。这个创建出来的 React 元素 代表了页面的 DOM 元素,因此又称为 虚拟DOM。
React.createElement(标签名,属性对象,标签里的内容 / 数组);
let n = 0;
let React = window.React;
let ReactDOM = window.ReactDOM;
//React.createElement("div",{className:"red"},n);
const App = React.createElement("div", { className: "red" }, [
n,
React.createElement(
"button",
{
onClick: () => {
n += 1;
}
},
"+1"
)
]);
3. 使用 ReactDOM 渲染到页面
let root = document.getElementById("root");
ReactDOM.render(App, root);
此刻在页面就会出现创建的元素。
但是发现点击按钮加一不起作用,那是因为 React 不像 Vue 一样会对数据进行监听,React 不会对数据进行监听,因此数据变化不会重新渲染页面,需要手工重新渲染页面,将加一后的n重新渲染一遍。
4. 手工渲染
onClick: () => {
n += 1;
ReactDOM.render(App, root);//添加渲染
}
但是此刻还是不能加一,那是因为,仔细看看,就会发现,App 是我们创建的一个 React 元素,是一个立即求值的语句,在执行到该语句时就会执行,并且只执行一次。
因此当我们重新渲染时,App 变量不会重新执行一遍从而获得最新的n的值,那么该如何让 App 元素在渲染时重新获取呢?
答案是是用函数,函数是可以延迟求值的。将 App 定义成一个函数,每次渲染时执行该函数,则会在每次执行时才获取当前 n 的值,就是我们需要的,因此修改如下。
5. React 元素改成 React 组件
将 App 元素改成 App 函数,每次执行函数来获取最新的数据值。这是 React 的精髓思路。
let n = 0;
let React = window.React;
let ReactDOM = window.ReactDOM;
//React.createElement("div",{className:"red"},n);
const App = () => React.createElement("div", { className: "red" }, [
n,
React.createElement(
"button",
{
onClick: () => {
n += 1;
console.log(n);//可用于判断是否加1了,加1了还是没有就是页面没重新渲染
ReactDOM.render(App(), root);
}
},
"+1"
)
]);
let root = document.getElementById("root");
ReactDOM.render(App(), root);
即可实现按钮点击加一。
6. 未完待续
上面虽然确实是实现了 demo,但是发现其特别复杂,尤其是创建一个元素时,语句很复杂,和 Vue 未使用 Vue-loader 时一样复杂的创建元素的语句,因此 React 也提供了一个和 Vue-loader 类似 React 的编译器,用于简化 React 的语句,在后篇博客介绍,此篇博客的方法是最原始的 React 的语法实现的 demo。
另外,需要补充的是,React 和 Vue 的设计思路完全不一样,Vue 是利用对数据进行监听来设计数据响应式来刷新页面局部更新的。React 是用重新渲染的方式刷新页面,React 每次都全部渲染一次看起来很傻是不是,其实,React 并不会每次全部渲染,它会在两次渲染之间找不同之处,也就是找到修改的部分,然后只重新局部渲染修改的部分。React 使用的两次渲染虚拟 DOM 找不同的算法叫做 DOM Diff 算法,Diff 即Different。
因此,React 和 Vue 一样都是以局部渲染的方式刷新页面。