1、React 简介
基于 HTML 的前端界面开发变得越来越复杂,其本质问题基本都可以归结于如何将来自于服务器端或者用户输入的动态数据高效的展示到前端界面上。Facebook 在这一问题上对市场上所有 JavaScript MVC 框架都不满意,就决定自己写一套,也就有了 React !
React 框架正是面向上述问题的一个解决方案,按官网描述,其出发点是:用于开发数据不断变化的大型应用程序(Building large applications with data that changes over time)。相比传统型的前端开发,React 开辟了一个相当另类的途径,实现了前端界面的高性能高效率开发。
React 被开发出来之后,大家发现这套东西很好用,就在 2013 年 5 月开源了。由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以越来越多的人开始关注和使用,现如今已是和 Vue 并肩的最热的两个前端框架之一 !
2、如何引入 React
- 通过 BootCDN 的方式引入 React
在使用 React 之前可以对其进行 BootCDN 引入,和 Vue 相比 React 的引入会稍微麻烦一点,它需要引入 React 和 React-DOM 两个库。引入完成之后在控制台打印一下,看是否引入成功。🚨:先引入 React 后引入 React-Dom。
<div id="app"></div> <script src="https://cdn.bootcss.com/react/16.13.1/umd/react.development.js"></script> <script src="https://cdn.bootcss.com/react-dom/16.13.1/umd/react-dom.development.js"></script> <script> // 你也可以引用生产版 min.js console.log(window.React); // React 对象 console.log(window.React.createElement); // React.creathElement 函数 console.log(window.ReactDOM); // React-Dom 对象 console.log(window.ReactDOM.render); // ReactDOM.render 函数 </script>
ps:在 BootCDN 引入库或插件时,可能会遇到 cjs 和 umd 两种形式:
cjs 全称 CommonJS,是 Node.js 支持的模块规范,umd 是统一模块定义,兼容各种模块规范(含浏览器)。
理论上优先使用 umd,同时支持 Node.js 和浏览器,最新的模块规范是使用 import 和 export 关键字。
- 通过 webpack 的方式引入 React
使用 BootCDN 的方式引入 React 的方式确实快捷方便,但是如果需要更新版本的话还需要再修改引入链接,这不免会给开发人员带来一些不必要的麻烦,所以推荐这种通过 webpack 的方式引入 React。而这种方式已经有成熟的脚手架了 create-react-app 帮我们配置好了,我们站在巨人的肩膀上就可以了,安装及创建项目的方式如下:
yarn global add create-react-app // 或者npm,由于内容比较大推荐使用 yarn create-react-app ProjectName // 类似于 Vue 的 vue create ProjectName // 运行 yarn start 命令,可以看到 React 的网页就说明项目创建成功了 create-react-app ProjectName --template typescript //如果你想支持 TypeScript
3、用 React 实现 +1 操作
完成第一阶段的引入操作,赶快用 React 来搞一个 +1 操作练练手吧!
<div id="root"></div> <script src="https://cdn.bootcss.com/react/16.13.1/umd/react.development.js"></script> <script src="https://cdn.bootcss.com/react-dom/16.13.1/umd/react-dom.development.js"></script> <script> const React = window.React // 如果是webpack或create-react-app,则不需要声明 const ReactDOM = window.ReactDOM // 如果是webpack或create-react-app,则不需要声明 let num = 0; // 创建App div如下,第二个参数是div的属性,第三个参数是表示div中的内容 const App = ()=> React.createElement('div', {className: 'red'}, [ // 这里的App必须是函数,否则无法刷新视图 num, React.createElement( // 在div内容的n后面再创建一个button按钮 'button', { onClick: ()=>{ // React不会像Vue一样,当你点击后自动刷新视图 num += 1; ReactDOM.render(App(), root); // 需手动刷新,但是App如果是个对象页面不会刷新 } // 对象只能执行一次,需要将 App 改成函数 ()=>{} }, // 因要实现手动刷新,将APP改为App() '+1' ) ]); const root = document.querySelector("#root"); ReactDOM.render(App(), root); // 将创建的App div插入到root div中,因要实现手动刷新,将APP改为App() </script>
为什么创建的 App 必须要是一个函数才能实现手动刷新视图?因为如果 App 是一个对象,它就只能执行一次,App 对象读取的变量 num 的值是声明的那一瞬间的值,即立即求值,所以当创建完 button 后手动渲染 App 时,页面上的 num 还是 0。如果 App 是函数就不一样了,函数是会在调用它的时候再求值,即延迟求值,且求值时会读取 num 的最新值。
const App1 = React.createElement('div', null, n) // App1 是一个React元素 const App2 = () => React.createElement('div', null, n) // App2 是一个React函数组件 // 函数App2是延迟执行的代码,会在被调用的时候执行
React 的 createElement() 方法的返回值 element 可以代表一个 div,但是这个 element 并不是真正的 div,而是一个 DOM对象,仅存在内存中,所以我们一般称 element 为 虚拟 DOM 对象。而 ()=> Reat.createElement() 是一个返回 element 的函数,也可以代表一个 div,这个函数可以多次执行,每次得到最新的虚拟 div 对象。React 会对比两个虚拟 div 对象,找出不同,然后局部更新视图,找不同的算法叫做「DOM Diff 算法」。