React 是什么

React 跟angular.js 和Vue.js 一样是构建用户界面的js库
2011 年 由Facebook 工程师Jordan Walke创建
在 2013 开源


React 的优势


原生js的痛点
  1. 原生的Javascript 操作DOM繁琐,效率低(DOM-API 操作UI)
  2. 使用Javascript 直接操作DOM, 样式数据改变时, 浏览器会进行大量重绘重排
  3. 原生Javascript 没有组件化编码方案, 代码复用率低。


React的优点
  1. 采用组件化模式, 声明式编码, 提高开发效率以及组件复用率。
    命令式编码: 必须告诉程序做一件事情的每个步骤.
    声明式编码: 告诉程序做1个件事, 不需要关心步骤, 如何实现.
  2. 在React Native 中可以使用React语法进行移动端(android / ios)开发.
  3. 使用虚拟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和jquery有什么区别 react和js的区别_html



而React 会引入一种虚拟DOM(VDOM)的东西, 在代码和 页面真实 DOM中构建了1个中间层

当数据首次被页面展示, 因为中间VDOM层的存在, 效率肯定时比原生更低的

但是当网页数据发生变化时, React会生成新的VDOM 然后与 内存中的旧VDOM比较, 然后只会更新被更改or新增的真实DOM。 这就是差异了

react和jquery有什么区别 react和js的区别_javascript_02


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

react和jquery有什么区别 react和js的区别_javascript_03


意思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

react和jquery有什么区别 react和js的区别_react.js_04


可见它无非就是js的一般对象