React 是什么
React 跟angular.js 和Vue.js 一样是构建用户界面的js库
2011 年 由Facebook 工程师Jordan Walke创建
在 2013 开源
React 的优势
原生js的痛点
- 原生的Javascript 操作DOM繁琐,效率低(DOM-API 操作UI)
- 使用Javascript 直接操作DOM, 样式数据改变时, 浏览器会进行大量重绘重排
- 原生Javascript 没有组件化编码方案, 代码复用率低。
React的优点
-
采用组件化模式, 声明式编码, 提高开发效率以及组件复用率。
命令式编码: 必须告诉程序做一件事情的每个步骤.
声明式编码: 告诉程序做1个件事, 不需要关心步骤, 如何实现. -
在React Native 中可以使用React语法进行移动端(android / ios)开发.
-
使用虚拟DOM 和 优秀的 diffing(比较出不同的地方)算法, 尽量减少于真实DOM 的交互.
这个是React的核心优势
什么是虚拟DOM 和其优势
先看下面原生html ES6 js 的例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="graphics_card">
</div>
<script>
let cardList = [
{card: 'RTX4090', comment: '旗舰,烧接口'},
{card: 'RTX4080', comment: '加价,智商检测卡'},
{card: '7900XTX', comment: '铺货弱,AMD YES!'}
]
let cardHtml = "";
cardList.forEach(card=>{
cardHtml += `<li>${card.card} - ${card.comment}</li>` // ` but not ''
});
document.getElementById('graphics_card').innerHTML = cardHtml
</script>
</body>
</html>
逻辑很简单, 无非就是展示三行关于显卡的数据.
但是如果当数据发生变化时, 基于下面这行代码, 浏览起就会对这个DOM重绘
document.getElementById('graphics_card').innerHTML = cardHtml
而这种DOM重绘时是不会重用旧有DOM的,当数据量大时, 例如在页面中展示1000条数据, 当增加1条数据到1001时, 旧有的1000数据的dom还是会被重绘, 效率就不高了。
而React 会引入一种虚拟DOM(VDOM)的东西, 在代码和 页面真实 DOM中构建了1个中间层
当数据首次被页面展示, 因为中间VDOM层的存在, 效率肯定时比原生更低的
但是当网页数据发生变化时, React会生成新的VDOM 然后与 内存中的旧VDOM比较, 然后只会更新被更改or新增的真实DOM。 这就是差异了
React怎样构建VDOM, Hello word 例子
react的依赖
❯ npm list
reactprj1@1.0.0 /home/gateman/Projects/jsproject/reactprj1
├── babel-standalone@6.26.0
├── react-dom@15.7.0
└── react@15.7.0
例子:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="test"></div> <!-- define a container -->
<script src="../node_modules/react/dist/react.min.js"></script>
<script src="../node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="../node_modules/babel-standalone/babel.min.js"></script>
<script type="text/babel">
//create virtual dom , single quotes is not need
const VDOM = <h1> Hello, React</h1>
//appy virtual dom to page
ReactDOM.render(VDOM, document.getElementById("test")) //first parameter is virtual dom, second parameter is container (div)
</script>
</body>
</html>
很简单, 无非构建1个VDOM对象, 然后利用ReactDOM.reader()方法去渲染这VDOM对象。映射成真实DOM对象
在例子中,
我们引用了babel 这个依赖, 注意script的类型时text/babel 而不再是默认的text/javascript
这就是所谓的jsx
例如下面这句, 在js中肯定是有语法错误的, 因为我们没有使用双引号。
const VDOM = <h1> Hello, React1 </h1>
所以我们在React中更多的是在写jsx 而 不是原生js, 当然浏览器是不认识js的, 所以我们需要babel和依赖去翻译jsx
当运行时
我们会在浏览器见到这warning
意思babel是在运行时翻译jsx的, 并不建议在生产环境中使用这种翻译模式, 因为更耗性能, 在生产环境中应该像用webpack那样先把jsx 翻译好再部署
为什么要使用jsx 而不是js
Jsx 就是用于构造VDOM的语法.
其实React 本身已经提供了创造VDOM的方法,
const VDOM = React.createElement('h1', {id: "title"}, "Hello, React")
第一参数时VDOM的类型, 第二个参数是 标签属性(组), 第三个是内容
等效于jsx的
const VDOM = <h1 id="title"> Hello, React1 </h1>
貌似差不多,
但是当我们构建1个复杂的嵌套VDOM是时
jsx可以很简单地实现
const VDOM = (
<h1 id="title">
<span id="subtitle"> Hello, React</span>
</h1>
)
而原生js要写成函数嵌套,
const VDOM = React.createElement('h1', {id: "title"},
React.createElement('span', {id:"subtitle"}, "Hello, React")
)
明显jsx方式更优雅, 可读性更好,在构建VDOM更像在写html
当然babel实际上会把jsx的方式翻译成原生js的方式, 所以预翻译就很重要了.
VDOM 在内存里究竟是个什么东西
很简单, 我们只需要再代码中print一下
ReactDOM.render(VDOM, document.getElementById("test")) ;
console.log('VDOM is:'. VDOM);
console.log(typeof VDOM);
console.log(VDOM instanceof Object);
debugger; //add a breakpoint stop here
可见它无非就是js的一般对象