React框架
React是一个JS库,可以简化可视化界面的开发,由Facebook在2013年发布。
为什么要学习React
那么为什么要学习React呢?
这要先从原生js的痛点出发,原生JS的痛点在于:
- 用DOM的API去操作DOM,过程十分繁琐,且效率低
- 用js直接操作DOM,浏览器会进行大量的回流和重绘
- 原生JS没有组件化,代码复用率低
那么,React又如何呢?
React特点
- 组件化开发,代码复用率高,提高开发效率
- 使用虚拟DOM和Diff算法,尽量减少与真是DOM的交互,提高页面性能
故前端常使用React框架来简化开发,提高开发效率。
React核心
(1)React基于JSX(JavaScript Xml)的语法,可以和html,js混合书写
JSX语法:组件可以以自定义标签的形式引用;
(2)组件(Component):是数据和逻辑的封装体,可以实现用户界面的模块化开发,提高了代码复用率、简化了开发,可维护性好。
React框架的最大优势在于:支持创建虚拟DOM,提高页面性能
JSX语法
(1)JSX就是JavaScript XML的缩写,是基于JavaScript的XML;
(2)通过React XML方式定义的虚拟DOM,最终也会转换为通过createElement()方法创建的节点。
语法详解
(1)一般语法形式:
const element=(
<tag-level-1> //根标签
<tag-level-2>
</tag-level-2>
</tag-level-1>
)
注意:
- element中必须有且只能有一个根标签;
- 模块化开发中(组件)允许使用<></>作为根标签
(2)JSX算术表达式:用大括号{}表示
例如:
const reactSpan = (
<span>
<h3>JSX算术表达式</h3>
<p>
1+2 = { 1+2 } //显示1+2=3
</p>
</span>
)
(3)JSX条件表达式:在JSX表达式中不能使用if语句,但是可以使用条件表达式(?:构成的表达式)
使用条件运算符:xx?xx:xx
const reactSpan = (
<span>
{1==1?'满足条件输出':'不满足条件输出'} //显示 满足条件输出
</span>
)
(4)JSX嵌入表达式:在外部定义变量,在虚拟DOM中通过‘{}’引用变量
(5)JSX对象表达式:可以通过“对项名.属性名”的方法使用
例如:
name='张三'
var obj={
name:'星子',
gender:'女',
}
const reactSpan = (
<span>
<p>姓名:{name}</p>
<p>姓名:{obj.name}</p>
<p>性别:{obj.gender}</p>
</span>
)
(6)JSX函数表达式:在JSX中可以直接调用JavaScript中的函数
var obj={
name:'星子',
gender:'女',
}
function showInfo(user){
return '姓名:'+user.name+'\n性别:'+user.gender;
}
const reactSpan = (
<span>
<p>{showInfo(obj)}</p>
</span>
)
React开发过程
(1)导入对应的js文件
<script src="../js/react.development.js"></script> <!--React核心库-->
<script src="../js/react-dom.development.js"></script> <!--React与Dom有关的库-->
<script src="../js/babel.min.js"></script> <!--用于将ES6转换为ES5-->
babel主要是用来将ES6或更高版本的js代码转换为ES5的代码,从而提高兼容性
(2)创建DOM
(3)进行DOM的渲染:React.render(虚拟DOM,实际DOM)
实际DOM
传统的HTML的UI设计,承载了数据的呈现和更新,浏览器在呈现DOM之前,要构建一颗DOM树,一旦该DOM树种某一个节点发生了变化,就必须重新构建树(从头开始遍历节点,直到改变了的节点);对于复杂的DOM,频繁的重建DOM树就会导致页面性能下降。
虚拟DOM
先构建一颗虚拟的DOM树,若树中的某一点发生了变化,只对虚拟DOM树进行局部更新,然后将虚拟的DOM渲染到实际的DOM中。
例如:
<div id="react-div"></div>
<script type="text/babel">
const reactDiv=document.getElementById('react-div')
var arr=[
<p>西柚</p>,
<p>薄荷</p>
]
const reactSpan=(
<span>
<p>{arr}</p>
</span>
)
ReactDOM.render(reactSpan,reactDiv)
</script>
React组件
React组件可以将UI切分成一些独立的,可复用的部件。React组件通过Props可以接收任意的输入值,因此Props也可以理解为参数的概念。
React语法是基于版本ES6实现的。因此,React组件除了通过JavaScript函数形式实现,还可以通过ES6 Class(类)的形式来实现。
注意:React组件的名称首字母必须大写
函数组件
通过JavaScript函数形式实现一个React函数组件:
基本用法:
<div id="react-div"></div>
<script type="text/babel">
const reactDiv=document.getElementById('react-div');
//定义一个函数组件
function HelloReact(){ //组件名(这里是函数名)的首字母必须大写
return <div>
<h2>React组件:</h2>
<p>我是函数组件</p>
</div>
}
ReactDOM.render(<HelloReact/>,reactDiv)
</script>
/*
const reactSpan=(
<span>
<HelloReact/> //将函数名作为标签
</span>
)
ReactDOM.render(reactSpan,reactDiv)
*/
类组件
通过ES6 Class(类)形式实现一个React类组件:
基本用法:
<div id="react-div"></div>
//定义类:必须是React.Component类的子类
class HelloReact extends React.Component{ //类名首字母必须大写
render(){
return <div>
<label>姓名:
<input type="text"/>
</label>
</div>
}
}
//组件渲染
ReactDOM.render(<HelloReact/>,document.getElementById('react-div'));
虚拟DOM渲染过程
先构建一颗虚拟的DOM树,若树中的某一点发生了变化,只对虚拟DOM树进行局部更新,然后将虚拟的DOM渲染到实际的DOM中。
JSX虚拟DOM渲染为真实DOM的原理和步骤:
(1)基于babel-preset-react-app把JSX语法变为React.createElement的模式;
使用 React.createElement或 JSX编写 React组件 ,实际上所有的 JSX代码最后都会转换成 React.createElement(), Babel帮助我们完成了这个转换的过程。
因为我们的 JSX 代码会被 Babel 编译为React.createElement,不引入 React 的话就不能使用React.createElement了。
(2)基于React.createElement方法执行创建出虚拟DOM对象(JSX对象);
createElement函数对 key和 ref等特殊的 props进行处理,并获取 defaultProps对默认 props进行赋值,并且对传入的孩子节点进行处理,最终构造成一个 ReactElement对象(所谓的虚拟 DOM)。
(3)基于ReactDOM.render把创建的虚拟DOM对象渲染到页面指定的容器中(变为真实DOM)。
ReactDOM.render将生成好的虚拟 DOM渲染到指定容器上,其中采用了批处理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实 DOM。