react是什么?
React用于构建用户界面的JS库。是一个将数据渲染为HTML视图的开源JS库。
为什么学?
1.原生JS操作DOM繁琐,效率低
2.使用JS直接操作DOM,浏览器会进行大量的重绘重排
3.原生JS没有组件化编码方案,代码复用低
在学习之前最好看一下关于npm的知识:下面是我在网上看见的一个写的还不错的npm的文章
npm
1.组件化开发,声明式编码,提高效率
2.在React Native中,使用React进行移动端开发
3.使用虚拟DOM+Diffing算法,减少真实DOM操作,大大提升效率
既然是原生H5,那么就要用script
标签引入React的js依赖
介绍一下需要的js依赖,这三个是非常基础的库,而且一定要按图上固定的顺序导入
最后引入babel标签,告诉编译器,这里需要去从JSX转换成JS
注意:如果类型写错了,会发生错误,导致浏览器不认识标签,因为JS中根本没有标签这一说
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello React!</title>
<meta charset="UTF-8">
<!-- 动态适配 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="css/style.css" rel="stylesheet">
</head>
<body>
<div id="test"></div><!--真实DOM-->
<script type="text/javascript" src="../js/react.development.js"></script> <!--React核心的库-->
<script type="text/javascript" src="../js/react-dom.development.js"></script><!--React操作Dom相关库-->
<script type="text/javascript" src="../js/babel.min.js"></script><!--将JSX转换成JS用的依赖,因为浏览器不认识JSX,只认识JS-->
<!-- 最后引入babel标签,这里是告诉编译器这里是JSX,需要用babel转换成JS文件
如果不小心写成其他的类型,那么浏览器就无法编译通过 -->
<script type="text/babel">
// 虚拟DOM创建
const virDom=<h1>hello React</h1>
// 将虚拟DOM渲染到某个指定的真实DOM上面
ReactDOM.render(virDom,document.getElementById("test"))
</script>
</body>
</html>
前置条件依旧是引入上面的三个依赖
其实JS也可以做成类似于JSX的写法
首先回顾一下
传统创建真实DOM元素,可以通过操作document对象来进行创建
document.createElement("div")
而我们创建虚拟DOM,因为我们引入了React依赖,所以就可以通过React对象创建虚拟DOM。注意,即使是JS创建,也不可以想当然的用双引号把元素括起来,因为React不认识这种写法
React.createElement("标签名","标签属性","标签内容")
例子:
const virDom=React.createElement("h1",{id:'title'},'这是内容')
这样我们就通过JS创建了一个虚拟DOM元素,但是这种创建方式创建单层元素还好,一旦创建很多元素就会非常麻烦
比如我要在DIV里面套一个span(span没属性)就得这样:
const virDom=React.createElement("h1",{id:'title'}, React.createElement("span",{},'这是span内容'))
如果元素过多就得层层套娃,非常痛苦
最后渲染指定真实DOM即可,注意这里就有意思了,因为是JS创建的,所以标签类型指定了JS,而不是Babel
<script type="text/javascript">
const virDom=React.createElement("h1",{id:'title'}, React.createElement("span",{},'这是span内容'))
// 虚拟DOM创建
// 将虚拟DOM渲染到某个指定的真实DOM上面
ReactDOM.render(virDom,document.getElementById("test"))
</script>
测试肯定好用,就不演示了
但这样非常麻烦,一个元素就快累疯了,所以引入了JSX
此时用JSX就非常容易标签套娃了
const定义的时候套一层括号代表是一个整体,写完标签,渲染到真实DOM上就可以了
<script type="text/babel">
// 虚拟DOM创建,JSX开始套娃
const virDom=(
<h1>
<h2>
<div>123</div>
</h2>
</h1>
)
// 将虚拟DOM渲染到某个指定的真实DOM上面
ReactDOM.render(virDom,document.getElementById("test"))
</script>
这里需要注意,因为JSX是JS+XML,所以如果不是单纯的标签语言,混入了一些JS,那么一定要用{}
把JS代码括起来
const virDom=(
<div>
<h1>前端js框架列表</h1>
<ul>
{
data.map((item,index)=>{
return <li key={index}>{item}</li>
})
}
</ul>
</div>
)
所以到这里,大概就可以才出来babel的原理了
通过babel把写好的JSX,一层一层标签去挨个套娃转换,最终转换成这种React.createElement的JS创建形式。
const virDom=React.createElement("h1",{id:'title'}, React.createElement("span",{},React.createElement(...n层标签)))
这也就是为什么前面控制台说,不建议用生产环境用Babel转换,这种转换的方式标签少的话还好,如果大量去现场从JSX转换成JS,那么会非常耗时,用户一进来看见一个白画面(等待从JSX转换成JS),这是很不友好的。后面开发时会替代这种写法。
关于虚拟DOM,本质就是Object,即为一般对象,所以相对于一个真实的DOM来说,更轻。
虚拟DOM是React内部在处理,无需真实DOM上的那么多属性。
但最后虚拟DOM还是会被转化为真实DOM,最后呈现在画面上。
JSX在创建虚拟DOM的时候,不可以用字符串引号创建,会导致无法识别
在JSX中,想用JS必须要用{}
套一下,套完代码就会被认为是JS代码
比如给一个div标签设置id,利用{}
进行读取
注意,React标签中,没有class属性,因为如果写了class就与ES6的语法相冲突,所以这里的class属性改名为className
如果React代码里写了class,就会被控制台提示是否是写错了
注意,class属性的话,是不需要去用{}
进行插值的,这属于原生的代码
在title属性中,定义一个css样式,准备在后面标签引用
在标签中直接以字符串的形式进行样式引用
样式生效
但是此时会被报错,也就是要改为className标记样式
改为className就没有报错了
所谓内联样式就是在标签上面直接标出css、
例子:
React中如果使用内联样式,则需要去用{{样式属性}}
标记,注意是两层花括号
则语法为:style={{key1:'value1' , key2:'value2'}}
这个不用多赘述,定义的那个虚拟DOM只保持一个根标签,图上多个就报错了
无论是单个或者多个标签,JSX中必须保持闭合
单个标签不闭合报错
闭合了即正确(2选1均可)
单标签闭合
双标签闭合
就将标签转化为html同名元素,如果html中无该标签对应的元素,就报错;
随便定义一个标签
react就去渲染对应的组件,如果没有就报错
直接认为是React标签,在React组件中找不到定义,则直接报错
关于JS表达式和JS语句分别是什么:
JS表达式:返回一个值,可以放在任何一个需要值的地方 a a+b demo(a) arr.map() function text(){}
JS语句:if(){} for(){} while(){} swith(){} 不会返回一个值
这二者如何区分呢?
就是用 一个变量去接这个代码,看看有没有返回值
为什么要说这个?
是因为,标签中混入JS表达式的时候要用{}
换句话说:
就是,{}
中只能放入JS表达式
渲染出来的效果
但是控制台会有报错
意思这种循环出来的标签,需要有自己的unique key,因为diffing算法需要用这个key,所以这里报错
稍加修改,用遍历时自动生成的index作为unique key,但是这种做法会有问题,但是这里先不用处理,后续学习中会说明