1.React介绍

多行html 空标签

在react的组件中多行html必须有一个父容器包裹 所以通常我们使用div来进行包裹 但是有的时候这些div是多余的 会在页面生成很多无用的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React from 'react'
import ReactDOM from 'react-dom'

class Demob extends React.Component {
render() {
return (
// 多行标签必须有一个父容器包裹
<div>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
</div>

)
}
}

ReactDOM.render(
<Demob></Demob>,
document.getElementById('root')
)

空标签

空标签 在页面是不进行展示的 它的作用仅仅就是用来描述多行标签的一个包裹作用

写法1:

<></>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React from 'react'
import ReactDOM from 'react-dom'

class Demob extends React.Component {
render() {
return (
// 空标签
<>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
</>

)
}
}

ReactDOM.render(
<Demob></Demob>,
document.getElementById('root')
)

写法2:

Fragment空标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React from 'react'
import ReactDOM from 'react-dom'

class Demob extends React.Component {
render() {
return (
// 空标签
<React.Fragment>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
<h1>你好我是一个标签</h1>
</React.Fragment>

)
}
}

ReactDOM.render(
<Demob></Demob>,
document.getElementById('root')
)

动态属性

属性插入变量使用:属性={属性值}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React from 'react'
import ReactDOM from 'react-dom'

class Demob extends React.Component {
render() {
let text="点我去百度"
let ahref="http://www.baidu.com"
return (
<>
<h1>属性插变量</h1>
{/* react中属性插变量 属性={你要插的值} */}
<a href={ahref}>{text}</a>
</>
)
}
}

ReactDOM.render(
<Demob></Demob>,
document.getElementById('root')
)

事件处理

在react中事件的绑定 使用小驼峰命名法

例:onclick 在react中 onClick onchange 在react中 onChange

绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了

绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了

绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了

绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了

基本事件操纵

事件绑定 使用小驼峰命名法 鼠标左键点击事件 onclick——》onClick onchange——》onChange

类组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React from 'react'
import ReactDOM from 'react-dom'

class Demob extends React.Component {
fun=()=>{
console.log("你好")
}
render() {
return (
<>
{/* 函数注意 */}
<button onClick={this.fun}>点我触发函数</button>
</>
)
}
}

ReactDOM.render(
<Demob></Demob>,
document.getElementById('root')
)

函数组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 我是函数组件的例子
import React from 'react'
import ReactDOM from 'react-dom'
let demo=()=>{
console.log("事件")
}

let Fun=()=>{

return (
<div>
<h1>我是一个函数组件</h1>
<button onClick={demo}>点我调用事件</button>
</div>
)
}

ReactDOM.render(
<Fun></Fun>,
document.getElementById('root')
)

函数参数传递

因为在react中函数调用的时候不加() 那我我们如果要传递函数的实参怎么传递?

1.使用bind方式进行传递

函数组件

1
<button onClick={fun.bind(this,"你好我是实参")}>点我</button>

类组件

1
<button onClick={this.fun.bind(this,"我是实参1","我是实参2")}>点我传递函数实参</button>

2.使用箭头函数调用函数进行传递

函数组件

1
<button onClick={()=>{fun("我是参数")}}>点我</button>

类组件

1
<button onClick={()=>{this.funb(1111,2222)}}>点我传递实参2</button>

阻止事件传播与默认行为

同原生js

事件对象

使用event

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React, { Component,Fragment } from 'react'

export default class Com extends Component {
// 直接传值event即可得到事件对象
fun=(event)=>{
console.log("您在输入框中是",event.target.value)
}
render() {
return (
<Fragment>

<h1>事件对象</h1>
<input type="text" onInput={this.fun}/>

</Fragment>
)
}
}

遍历展示

react推荐使用map方法来进行数据的便利

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
import React, { Component } from 'react'
let arr = [111, 222, 333, 444, 555, 666, 777];
export default class democ extends Component {
render() {
return (
<React.Fragment>
<h1>便利数据</h1>
<ul>

{
arr.map((v,i)=>{
return (
<li key={i}>{v}</li>
)
})
}

</ul>


</React.Fragment>
)
}
}

遍历复杂数据

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
48
49
50
51
52
import React, { Component } from 'react'
let arr = [111, 222, 333, 444, 555, 666, 777];
let obj=[
{name:"xix1i",age:181},
{name:"xix2i",age:182},
{name:"xix3i",age:183},
{name:"xix4i",age:184},
{name:"xix5i",age:185},
{name:"xix6i",age:186}
]
export default class democ extends Component {
render() {
return (
<React.Fragment>
<h1>便利数据</h1>
<ul>

{
arr.map((v,i)=>{
return (
<li key={i}>{v}</li>
)
})
}

</ul>

<hr />

<table border="1">
<tbody>
{
obj.map((v,i)=>{
return (
<tr key={i}>
<td>{v.name}</td>
<td>{v.age}</td>
</tr>
)
})
}
</tbody>
</table>




</React.Fragment>
)
}
}

ref

函数组件 无状态组件 不能使用ref

ref 标识组件内部的元素 就给组件的dom元素起个名字

函数组件是不能直接使用ref的

ref写法的分类

1.字符串(官方已经不推荐使用了)

2.回调函数(官方推荐方式)

回调函数的方式 就是在dom节点上挂载一个函数 函数的入参 就是dom节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from 'react'
import ReactDOM from 'react-dom'

class Demob extends React.Component {
fun=()=>{
console.log(this.demoinput.value)
}
render() {
return (
<div>
<h1>ref的例子</h1>
{/* 回调函数的方式创建ref */}
{/* <input type="text" ref={(text这个变量代表的就是当前这个input标签)=>{this.demoinput(随便创建一个变量)=text}}/> */}
<input type="text" ref={(text)=>{this.demoinput=text}}/>
<button onClick={this.fun}>点我得到输入框的值</button>
</div>
)
}
}

ReactDOM.render(
<Demob></Demob>,
document.getElementById('root')
)

3.React.createRef()(16.8版本新增的 官方推荐)

react 16.8新增的一种方式 我们通过初始化createRef从而得到ref对象 插入到页面中

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
import React from 'react'
import ReactDOM from 'react-dom'

class Demob extends React.Component {
// 1.创建
inputref=React.createRef()
fun=()=>{
// 3.使用
console.log(this.inputref.current.value)
}
render() {
return (
<div>
<h1>createRef</h1>
{/* 2.绑定 */}
<input type="text" ref={this.inputref}/>
<button onClick={this.fun}>点我得到输入框的值</button>
</div>
)
}
}

ReactDOM.render(
<Demob></Demob>,
document.getElementById('root')
)

扩展–插入字符串标签

在vue中插入字符串标签使用v-html这个指令即可完成

在今后实际工作的时候 会出现后台给你返回的就是一大段生成好的html 你需要把他展示在页面上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { Component } from 'react'

export default class demod extends Component {
state={
newhtml:"<h1>我是h1我是一段字符串标签</h1>"
}
render() {
return (
<div>
demod
{/* 插入字符串标签 */}
<div dangerouslySetInnerHTML={{__html:this.state.newhtml}}>
</div>
</div>
)
}
}

条件渲染

在开发中 创建不同的组件来封装我们需要完成的各个内容 但是我们需要根据程序的状态变化来渲染其中一部分内容

if语句来看进行条件渲染

在react中if条件渲染是最简单的 但是但是但是但是 注意 在jsx不允许出现if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React, { Component } from 'react'

export default class demo extends Component {
render() {
let newhtml=""
let num=1

if(num==1){
newhtml= <h1>吃饭</h1>
}else if(num==2){
newhtml= <h1>睡觉</h1>
}else{
newhtml=<h1>打豆豆</h1>
}
return (
<div>
{newhtml}
</div>
)
}
}

三元运算符

使用图片

1.把图片放到public文件夹中 直接使用图片名

2.不在public下 我们可以使用require()来进行引用

1
<img src={require("../assets/2.webp")} />

3.不在public下 我们也可以使用导入式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React, { Component } from 'react'

// 1.引入图片
import imgA from "../assets/2.webp"
export default class demob extends Component {
render() {
return (
<div>
{/* <img src="img/1.webp" /> */}

{/* <img src={require("../assets/2.webp")} /> */}

{/* 2.使用 */}
<img src={imgA} />
</div>
)
}
}

5 组件的数据挂载方式

状态state

状态(变量/数据)机制 在react中我们只需要把数据定义在state中 那么数据改变了页面也会发生改变

通过状态就可以让页面内容在不操作dom的情况下 进行相应式的改变

函数组件也叫无状态组件 所以函数组件中不能使用状态 (react16.8新增了一个叫HOOK的技术可以实现)

函数组件也叫无状态组件 所以函数组件中不能使用状态

使用

1.定义状态数据方式1

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
import React, { Component } from 'react'

export default class demob extends Component {
// 初始化state状态数据需要放到constructor中进行初始化
// es6中继承的规则中得知 子类是可以不写constructor 他会在实例化的时候
// 自动补充一个

// 但是如果你写了 那么必须在其中写super() 因为super就是调用父类的构造方法
// 此时子类才有this
constructor() {
super()
// 初始化state
this.state={
text:"我是字符串",
num:888,
bool:true,
arr:[1111,2222,333],
obj:{
name:"xiaoyang"
}
}
}
render() {
return (
<>
<h1>我是测试state使用的例子</h1>
</>
)
}
}

定义状态数据方式2

这种方式也是没有问题的 而且简单 但是 你去公司了 你看看你同事这样子写没有 如果没有 你就不要用了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React, { Component } from 'react'

export default class demob extends Component {

state={
text:"我是字符串",
num:888,
bool:true,
arr:[1111,2222,333],
obj:{
name:"xiaoyang"
}
}

render() {
return (
<>
<h1>我是测试state使用的例子</h1>
</>
)
}
}

2.使用state数据

this.state 是纯js对象,在vue中,data属性是利用 Object.defineProperty 处理过的,更改data的数据的时候会触发数据的 getter 和 setter ,但是React中没有做这样的处理,如果直接更改的话,react是无法得知的,所以,需要使用特殊的更改状态的方法 setState

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
import React, { Component } from 'react'

export default class demob extends Component {
// 初始化state状态数据需要放到constructor中进行初始化
// es6中继承的规则中得知 子类是可以不写constructor 他会在实例化的时候
// 自动补充一个

// 但是如果你写了 那么必须在其中写super() 因为super就是调用父类的构造方法
// 此时子类才有this
constructor() {
super()
// 初始化state
this.state={
text:"我是字符串",
num:888,
bool:true,
arr:[1111,2222,333],
obj:{
name:"xiaoyang"
}
}
}
render() {
return (
<>
{/* 2.使用state数据 */}
<h1>我是测试state使用的例子----{this.state.num}</h1>


</>
)
}
}

3.修改state的数据

this.setState({你修改谁:修改成什么})

修改state的数据必须使用setState修改之后页面才会发生改变

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
import React, { Component } from 'react'

export default class demob extends Component {
// 初始化state状态数据需要放到constructor中进行初始化
// es6中继承的规则中得知 子类是可以不写constructor 他会在实例化的时候
// 自动补充一个

// 但是如果你写了 那么必须在其中写super() 因为super就是调用父类的构造方法
// 此时子类才有this
constructor() {
super()
// 初始化state
this.state={
text:"我是字符串",
num:888,
bool:true,
arr:[1111,2222,333],
obj:{
name:"xiaoyang"
}
}
}

fun=()=>{
// 修改state的数据
this.setState({
num:123,
text:"xiaoyang"
})
}


render() {
return (
<>
{/* 2.使用state数据 */}
<h1>我是测试state使用的例子----{this.state.num}---{this.state.text}</h1>
<button onClick={this.fun}>点我修改</button>

</>
)
}
}

调用了setState之后发生了什么?

setState是异步的

(如果有大量数据修改的话不会因为修改数据而造成程序的卡顿)

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
48
49
50
51
52
53
54
55
import React, { Component } from 'react'

export default class demob extends Component {
// 初始化state状态数据需要放到constructor中进行初始化
// es6中继承的规则中得知 子类是可以不写constructor 他会在实例化的时候
// 自动补充一个

// 但是如果你写了 那么必须在其中写super() 因为super就是调用父类的构造方法
// 此时子类才有this
constructor() {
super()
// 初始化state
this.state={
text:"我是字符串",
num:888,
bool:true,
arr:[1111,2222,333],
obj:{
name:"xiaoyang"
}
}
}

fun=()=>{
// 修改state的数据
// this.setState({
// num:123,
// text:"xiaoyang"
// })
// 下面的console.log打印的结果是修改之后的 还是修改之前的?
// 是修改之前的结果 所以从而证明了setState是一个异步任务
// console.log(this.state.num)

// 但是我就是想setState修改完数据之后 打印新的结果怎么办?
// 因为setState是异步 异步都会有回调函数
this.setState({
num:123,
text:"xiaoyang"
},()=>{
// setState第二个参数是一个回调函数 当数据修改完他才会调用
console.log(this.state.num)
})
}

render() {
return (
<>
{/* 2.使用state数据 */}
<h1>我是测试state使用的例子----{this.state.num}---{this.state.text}</h1>
<button onClick={this.fun}>点我修改</button>
</>
)
}
}

调用了setState之后会自动触发render渲染

render就是渲染方法 只有render方法执行了 那么页面才会根据数据的改变而随之发生改变