React学习
踏歌行 2023-08-12
框架
阅读量:
# 基础
# 什么是React
React 是一个用于构建用户界面 (将数据渲染为HTML视图) 的 JAVASCRIPT 库。 React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。
尚硅谷React(零基础入门到精通/男神天禹老师亲授) (opens new window)
React的特点:
- 声明式编码、组件化模式
- 使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互
- React会根据数据,先生成虚拟DOM,对比跟原来的虚拟DOM比较,再生成真实DOM
- 在react native中使用react语法进行移动端开发
# 虚拟DOM和真实DOM
<!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>hello_react</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id = "test"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
// 1 创建虚拟DOM
const VDOM = <h1 id="title">Hello,React</h1> //jsx写法。这里不能写引号,因为不是字符串
//嵌套 jsx的优势:更简单的创建虚拟DOM
const VDOM2 = <h1 id="title"><span>Hello,React </span></h1>
//更好看的写法.
const VDOM3 = (
<h1 id="title">
<span>
Hello,React
</span>
</h1>
)
// 2 渲染虚拟DOM到页面
ReactDOM.render(VDOM, document.getElementById('test'));
//虚拟DOM
console.log(VDOM);//{$$typeof: Symbol(react.element), type: 'h1', key: null, ref: null, props: {…}, …}
console.log(typeof VDOM);//Object
//真实DOM
const TDOM = document.getElementById('test');
console.log(TDOM);//div#test .......
console.log(typeof TDOM);//Object
/*
关于虚拟DOM
1 本质是Object
2 虚拟DOM只在React内部用,比真实DOM的属性少很多
*/
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 组件实例的三大核心属性1:state
复杂组件有state,简单组件无state
State的作用: 人 状态 影响 行为 组件 状态 影响 行为
# 组件实例的三大核心属性2:props
传参
# 组件实例的三大核心属性3:refs与事件处理
# 生命周期回调函数/生命周期钩子函数
组件的生命周期可分成三个状态:
- Mounting(挂载):已插入真实 DOM
- Updating(更新):正在被重新渲染
- Unmounting(卸载):已移出真实 DOM
# jsx
全称Javascript XML, 类似于XML的JS扩展语法 本质是React.createElment(component, props, children)方法的语法糖。
# 组件通信
https://www.jianshu.com/p/fb915d9c99c4
- 使用 props (父传子)
- 使用 props 回调 (子传父)
- 使用 context 对象(全局)
- 使用事件订阅(比如PubSubJs库和postalJS库)
# 函数式组件
# UseEffect
最常用的三个钩子模拟方法如下:
- 模拟componentDidMount:
useEffect(()=>{console.log('首次渲染页面')},[ ])
1
- 模拟componentDidUpdate:
useEffect(()=>{console.log('任意属性变更')})
useEffect(()=>{console.log('指定元素n变更')},n)
1
2
2
- 模拟componentWillUnmoun:
useEffect(()=>{console.log('首次渲染')
return()=>{
console.log('即将卸载')
}
1
2
3
4
2
3
4
# UseRef
作用:
- 管理 DOM ref,相当于id
- 还相当于 this , 可以存放任何变量.
# 例子
<!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>hello_react</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id = "test"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
// 1 创建函数式组件 首字母大写
function MyComponent(){
console.log(this);//undefined babel 翻译了这里。使用了严格模式
return <h2> 我是用函数定义的组件,适用于简单组件的定义 </h2>
}
// 2 渲染组件到页面
//react-dom.development.js:500 Warning: Functions are not valid as a React child
//ReactDOM.render(MyComponent, document.getElementById('test'));
//输入标签。标签必须自闭合
//ReactDOM.render(<MyComponent/>, document.getElementById('test'));
ReactDOM.render(<MyComponent></MyComponent>, document.getElementById('test'));//React帮忙调用了
//ReactDOM.render(MyComponent(), document.getElementById('test'));//自己调用
/*
执行RecatDOM.render时,发生了什么:
1 React解析组件标签 找到组件MyComponent
2 发现组件是使用函数定义,随后调用该函数。
3 将返回的虚拟DOM转换为真实DOM,然后呈现在页面中
*/
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 类式组件
# 例子
<!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>hello_react</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id = "test"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
// 1 创建类式组件 继承React.Component
class MyComponent extends React.Component{
//render 必须写
//render放在类原型(MyComponent.propertype)对象上,供实例使用
render(){
console.log("render 中的this 是: ", this);//该类MyComponent的实例对象:包含三大属性props, refs, state 等
return <h2> 我是用类定义的组件,适用于复杂组件的定义 </h2>
}
}
// 2 渲染组件到页面
ReactDOM.render(<MyComponent></MyComponent>, document.getElementById('test'));
/*
执行RecatDOM.tender时,发生了什么:
1 React解析组件标签 找到组件MyComponent
2 发现组件是使用类定义,随后new 该类的实例,并通过该实例调用到原型上的render方法
3 将返回的虚拟DOM转换为真实DOM,然后呈现在页面中
*/
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 路由
# 路由以及状态管理
SPA (single page app单页面应用):整个应用只有一个完整的页面 点击页面中的链接 不会刷新页面。 只会做页面的局部刷新。
路由:一个路由是一个映射关系(key: value) Key是路径,value是function或component
- 后端路由:value是函数function,处理客户端提交的请求。
- 前端路由:依赖于History
# History:前端路由的记录(栈的结构)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>前端路由的基石_history</title>
</head>
<body>
<a href="http://www.atguigu.com" onclick="return push('/test1') ">push test1</a><br><br>
<button onClick="push('/test2')">push test2</button><br><br>
<button onClick="replace('/test3')">replace test3</button><br><br>
<button onClick="back()"><= 回退</button>
<button onClick="forword()">前进 =></button>
<script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script>
<script type="text/javascript">
// let history = History.createBrowserHistory() //方法一,直接使用H5推出的history身上的API
let history = History.createHashHistory() //方法二,hash值(锚点)
function push (path) {
history.push(path)
return false
}
function replace (path) {
history.replace(path)
}
function back() {
history.goBack()
}
function forword() {
history.goForward()
}
history.listen((location) => {
console.log('请求路由路径变化了', location)
})
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# React-router-dom
为web设计的react-router。 Route 路由 的英文 Router 路由器 的英文 路由器来管理路由
# React Native
React Native使用 JavaScript 编写应用逻辑,UI 则可以保持全是原生的。这样的话就没有必要就 HTML5 的 UI 做出常见的妥协
# 实践经验
# 脚手架create-react-app
SPA (single page app单页面应用)
# 功能界面的组件化编码流程
- 1拆分组件
- 2实现静态组件
- 3 实现动态组件
- 动态显示初始化数据: 数据类型;数据名称;保存在哪个组件
- 交互,从绑定事件监听开始
# UI组件库
- Ant-design (国内蚂蚁金服)
- Element UI 饿了么公司
- Vant 适合移动端 有赞公司
- Bootstrap twitter公司
- Material-ui 谷歌