用于构建用户界面的JS库。
是2013年Facebook开源的JS框架。
允许我们只需要维护自己的状态,当状态改变时,react可以根据最新的状态去渲染UI界面。
UI=f(state)
state改变,通过function函数重新渲染UI
如何合理的进行组件的划分(复用性)和设计是重点。
react
react-native
reactVR
这三个库各司其职,目的是让每一个库只单纯做自己的事情(Vue只是依赖一个vue.js文件)
1.react 包含react所必须的核心代码
2.react-dom react渲染在不同平台所需要的核心代码
react-dom针对web和native所完成的事情不同
web:react-dom会将jsx最终渲染成真实的DOM,显示在浏览器中
native:react-dom会将jsx最终渲染成原生的控件(比如的Android的Button,iOS的UIButton)
3.babel 将jsx转换成react代码的工具
Babel又名Babel.js。react里面有一个React.renderElement()来渲染元素,jsx按照普通的html的方法开发界面,通过babel转成React.renderElement(),这些东西可以直接跑在浏览器里面,而且可以直接被使用生成虚拟DOM。
1.CDN引入
<!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
<!-- crossorigin这个属性的目的是为了拿到跨域脚本的错误信息 -->
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
2.下载后,添加本地依赖
3.通过npm管理
命令式编程:每做一个操作,都是给计算机(浏览器)一步步命令。
<h2 class="title"></h2>
<button class="btn">改变文本</button>
<script>
// 1.定义数据
let message="hello world";
// 2.将数据显示在h2元素中
const titleEl=document.getElementsByClassName('title')[0];
titleEl.innerHTML=message;
// 3.点击按钮,界面的数据发生改变
const btnEl=document.getElementsByClassName('btn')[0];
btnEl.addEventListener('click',e=>{
message='hello react';
titleEl.innerHTML=message;
})
</script>
<body>
<div>Header</div>
<div id="app">app</div>
<div>Footer</div>
<!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
<!-- crossorigin这个属性的目的是为了拿到跨域脚本的错误信息 -->
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- 注意事项:使用jsx,并且希望script中的jsx的代码被解析,必须在script标签中添加type属性 -->
<script type="text/babel">
// ReactDom.render(渲染的内容,挂载的对象)
// jsx代码,会把原本app里面的东西覆盖掉
ReactDOM.render(<h2>hello world</h2>,document.getElementById("app"))
</script>
</body>
<script type="text/babel">
// jsx特点:多个标签最外层只能有一个标签
function btnClick(){
// message的数据发生改变了之后,要重新渲染DOM,才能拿到最新的数据
message="hello react"; // 页面并没有更新,控制台数据改变
render(); // 页面更新
}
let message="hello world";
function render(){
ReactDOM.render(
<div>
<h2>{message}</h2>
<button type="button" onClick={btnClick}>改变文本</button>
</div>,
document.getElementById("app"));
}
render();
</script>
<script type="text/babel">
// 封装App组件
class App extends React.Component{
// 一般在构造器中定义属性
constructor(){
super(); // 初始化父类实例
// this.message="hello world";
// state是固定的
this.state={
message:"hello world"
}
}
// render函数不用手动调用
render(){
// 需要渲染的东西有多个时,加个小括号括起来
return (
<div>
// {this.message}
<h2>{this.state.message}</h2>
// 不加this找不到当前对象的btnClick函数
//
<button type="button" onClick={this.btnClick.bind(this)}>改变文本</button>
</div>
)
}
btnClick(){
// this.message="hello react"; // 并不会改变,报错,this是undefined,函数定义的位置是在类里面,但是调用的位置是内部按钮发生点击的时候,在内部进行回调的,btnClick.apply(undefined) 用bind改变this指向之后,this指向App对象了
// this.render(); //手动调用没有效果,此时界面并没有改变,只是重新执行一遍render函数,并不知道数据已经改变了
// this.state.message="hello react"; // render函数不会重新执行,控制台数据已经改变了,但是界面没有更新
// 改数据并且内部会调用render函数
this.setState({
message:"hello react"
})
}
}
// 渲染App组件
ReactDOM.render(<App/>,document.getElementById("app"));
</script>
渲染逻辑:
ReactDOM里面渲染一个组件App,组件App里面有一个render函数,render函数里面返回需要渲染的元素。
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app">
</div>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
class App extends React.Component{
constructor(){
super();
}
render(){
return(
<div>
Hello World
</div>
)
}
}
ReactDOM.render(<App/>,document.getElementById("app"));
</script>
</body>
</html>
在VSCode中,把上述代码复制
1.文件==>首选项==>用户代码片段
2.选择代码片段文件 html.json
3.去snippet generator这个网站,格式化代码片段 网站链接
{
"create react snippet": {
"prefix": "reactapp",
"body": [
"",
"",
"",
" ",
" ",
" ",
"",
"",
" ",
"",
" ",
" ",
" ",
"",
" ",
"",
""
],
"description": "create react snippet"
}
}
1.操作dom兼容性问题;
2.过多兼容性代码的冗余问题;
3.代码组织和规范的问题。
vue的缺点:
是使用的模板,模板内部的东西不单独抽成一个组件,不好实现复用;react只需要抽取成变量就可以实现复用。
在vue中,通过指令来控制,v-if,v-show;
在react中,条件判断都和普通的JS代码一致;
React的组件相对于Vue更加灵活多样。
在Vue中:
通过传入一个对象;
<div class="static"
v-bind:class="{active:isActive,'text-danger':hasError}">
</div>
通过传入一个数组;
<div v-bind:class="[activeClass,errorClass]"></div>
对象和数组混合使用;
<div v-bind:class="[{active:isActive},errorClass]">
</div>
在React中:
原生;
<h2 className={"foo bar baz title active"}>我是标题1</h2>
<h2 className={"title" + (isActive ? " active" : "")}>我是标题2</h2>
<h2 className={["title" + (isActive ? "active" : "")].join(" ")}>我是标题3</h2>
classnames库;