写在前面

引入了 React 之后,开始使用 React 做一个小的 demo,即实现一个按钮点击加一,使用 CDN 引入 React,使用在线工具 codesandbox 的原生 JS 项目编写。

1. 引入 React 和 ReactDOM

在 index.html 中使用 BootCDN 引入 React 和 ReactDOM

  1. <script src="https://cdn.bootcss.com/react/16.13.1/umd/react.production.min.js"></script>
  2. <script src="https://cdn.bootcss.com/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
  3. <script src="src/index.js"></script>

引入后在 index.js 中输出 React 对象看一下,注意:使用 BootCDN 引入的都会变成全局对象,挂在 window 上,因此若无法直接访问到 React,就使用 window.React 访问 React 对象。

  1. console.log(window.React);

Snipaste_2020-04-10_17-02-09.png

2. 使用 React 创建虚拟 DOM

React 有提供 createElement API 接口 ,用于创建页面中需要的 DOM 元素,由于不是使用 DOM 的 API 直接创建一个真实的 DOM 元素,而是依据 React 的语法创建一个 React 元素,再由 React 负责将元素插入到页面中去。这个创建出来的 React 元素 代表了页面的 DOM 元素,因此又称为 虚拟DOM。

React.createElement(标签名,属性对象,标签里的内容 / 数组);

  1. let n = 0;
  2. let React = window.React;
  3. let ReactDOM = window.ReactDOM;
  4. //React.createElement("div",{className:"red"},n);
  5. const App = React.createElement("div", { className: "red" }, [
  6. n,
  7. React.createElement(
  8. "button",
  9. {
  10. onClick: () => {
  11. n += 1;
  12. }
  13. },
  14. "+1"
  15. )
  16. ]);

3. 使用 ReactDOM 渲染到页面

  1. let root = document.getElementById("root");
  2. ReactDOM.render(App, root);

此刻在页面就会出现创建的元素。
Snipaste_2020-04-10_17-23-00.png
但是发现点击按钮加一不起作用,那是因为 React 不像 Vue 一样会对数据进行监听,React 不会对数据进行监听,因此数据变化不会重新渲染页面,需要手工重新渲染页面,将加一后的n重新渲染一遍。

4. 手工渲染

  1. onClick: () => {
  2. n += 1;
  3. ReactDOM.render(App, root);//添加渲染
  4. }

但是此刻还是不能加一,那是因为,仔细看看,就会发现,App 是我们创建的一个 React 元素,是一个立即求值的语句,在执行到该语句时就会执行,并且只执行一次。
因此当我们重新渲染时,App 变量不会重新执行一遍从而获得最新的n的值,那么该如何让 App 元素在渲染时重新获取呢?

答案是是用函数,函数是可以延迟求值的。将 App 定义成一个函数,每次渲染时执行该函数,则会在每次执行时才获取当前 n 的值,就是我们需要的,因此修改如下:

5. React 元素改成 React 组件

将 App 元素改成 App 函数,每次执行函数来获取最新的数据值。这是 React 的精髓思路。

  1. let n = 0;
  2. let React = window.React;
  3. let ReactDOM = window.ReactDOM;
  4. //React.createElement("div",{className:"red"},n);
  5. const App = () => React.createElement("div", { className: "red" }, [
  6. n,
  7. React.createElement(
  8. "button",
  9. {
  10. onClick: () => {
  11. n += 1;
  12. console.log(n);//可用于判断是否加1了,加1了还是没有就是页面没重新渲染
  13. ReactDOM.render(App(), root);
  14. }
  15. },
  16. "+1"
  17. )
  18. ]);
  19. let root = document.getElementById("root");
  20. 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 一样都是以局部渲染的方式刷新页面。

完整 demo

React-demo1