React 组件
Galloping_Leo 2020-09-29 React
# 函数组件
- 就是使用 JS 中的函数创建的组件,叫做函数组件。
const Hello = () => <div>这是通过箭头函数创建的组件</div>
1
约定1:必须有返回值
- 返回值可以为null,表示不渲染任何内容
- 如果想要渲染内容,一般就是返回
JSX
约定2:组件名称必须以大写字母开头
- 用来区分普通的
react
元素 和reac
t组件
- 用来区分普通的
约定3:使用函数名称作为组件的标签名称来渲染
ReactDOM.render(<Hello />, root)
# ES6中的class
- 语法:
class Person {
// 添加属性:
constructor(age) {
this.name = 'jack'
this.age = age
}
// 添加实例方法
say() {}
}
const p = new Person(30)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- 继承:
// 父类
class Person {
constructor() {
this.name = 'zhangsan'
}
}
// 子类
class Chinese extends Person {
constructor() {
// 注意:手动调用super()
// super 即 父类中的构造函数(constructor)
super()
// this. ....
}
}
// 创建子类的实例对象,此时,c 就可以直接使用父类中的属性或方法了
const c = new Chinese()
// c => { name: 'zhangsan' }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 类组件
- 类组件:通过 ES6 中的class创建的组件,叫做 类组件
- 函数组件中的约定都适用于类组件
- 约定:类组件必须得继承自 React.Component 父类
- 约定:类组件中必须提供一个 render 方法,通过 render 方法的返回值来指定要渲染的内容
// 类组件
class Hello extends React.Component {
// render 方法是 React 中固定的一个方法名称
render() {
// return null
return <h1>这是我的第一个 class 组件</h1>
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 将组件抽离到独立的JS文件中
// 注意:不管是函数组件还是类组件,或者使用 JSX ,都需要导入 React!!!
import React from 'react'
// 创建 class 组件
// class Hello1 extends React.Component {
// render() {
// return <div>这是一个独立的组件</div>
// }
// }
// JSX -> React.createElement()
const Hello1 = () => <div>这是一个独立的组件</div>
// 导出组件
export default Hello1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 绑定事件
- 1 给 JSX 添加 onClick
- 2 在 {} 中,指定事件处理程序的名称(也就是一个函数名称)
const handleClick = () => {}
<button onClick={handleClick}></button>
1
2
3
2
3
// 在类组件中绑定事件
class Hello extends React.Component {
// 事件处理程序
handleClick() {
console.log('你点我!')
}
render() {
return <button onClick={this.handleClick}>点我 - class</button>
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 事件对象
- 如何获取到事件对象?通过事件处理程序的参数 e 来获取到
- React 中的事件对象是一个 合成事件。
- 使用方式,与原生DOM中的使用方式相同。
# 有状态组件和无状态组件
- 有状态组件:class(类)组件
- 职责(什么时候使用):负责更新UI(页面),也就是如果页面中的内容,需要变化
- 动
- 无状态组件:函数组件
- 职责:负责展示内容
- 静
# class组件中的状态
- 状态(state)即数据
- 如何初始化状态?
class Hello extends React.Component {
constructor() {
super()
// 状态初始化
this.state = {
count: 0
}
}
// 简化语法:
// state = {
// count: 66
// }
// 在 JSX 中使用状态
render() {
return <div>计数器:{ this.state.count }</div>
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# setState
- 作用:1 修改state 2 更新UI(页面)
- 语法:
this.setState({
count: this.state.count + 1
})
1
2
3
2
3
- 注意:不要直接修改 state !!!
- 错误演示:
this.state.count += 1
!!!
- 错误演示:
# 事件处理程序中this指向问题
- 1 箭头函数:
// 事件处理程序中,我们要的 this 是当前组件的实例对象(它是React在渲染组件时创建)
class Hello extends React.Component {
// 简化语法:
state = {
count: 0
}
handleClick() {
this.setState({ ... })
}
render() {
console.log('render:', this)
return (
<div>
计数器:{this.state.count}{' '}
<button onClick={() => this.handleClick()}>+1</button>
</div>
)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- 2 使用 bind 方法解决:
constructor() {
this.handleClick = this.handleClick.bind(this)
}
render() {
// 此处的 handleClick 就是绑定 this 后的事件处理程序了
return (
<button onClick={this.handleClick}></button>
)
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- 3 利用 class 实例方法的箭头函数形式:(推荐)
class Hello extends React.Component {
handleClick = () => {
this.setState({ ... })
}
render() {
return (
<button onClick={this.handleClick}></button>
)
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 受控组件
- 受控组件:其值收到 react 控制的表单元素,叫做受控组件
state = {
txt: ''
}
changeTxt = e => {
this.setState({
txt: e.target.value
})
}
render () {
return <input type="text" value={this.state.txt} onChange={this.changeTxt} />
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 表单处理
使用一个处理函数来处理多种类型的表单元素变化
给表单元素添加
name
属性,名称与state
相同根据表单元素类型获取对应值
在
change
事件处理程序中通过[name]
来修改对应的state
点击显示代码
import React, { Component } from 'react'
import styles from './index.module.scss'
export default class Form extends Component {
state = {
input: '',
textarea: '',
sports: [],
words: {
A: false,
B: false,
C: false
},
select: "B"
}
handleSubmit = (e) => {
e.preventDefault()
console.log(this.state)
// 发送请求
//...
}
//统一处理表单元素的的函数
handleChange = (name, e) => {
if (e.target.type === 'checkbox') {
let stateOption = this.state[name]
let isIncludes = stateOption.includes(e.target.value)
if (!isIncludes && e.target.checked) stateOption.push(e.target.value)
if (isIncludes && !e.target.checked) stateOption.splice(stateOption.findIndex(v => v === e.target.value), 1)
this.setState({
[name]: stateOption
})
} else {
this.setState({
[name]: e.target.value
})
console.log(e.target.value)
}
}
render() {
const {
input,
textarea,
words,
select
} = this.state
return (
<div className={styles.root}>
<form className={styles.form} onSubmit={this.handleSubmit}>
<input
type="text"
name="input"
className={styles.input}
onChange={(e) => { this.handleChange('input', e) }} />
<textarea name="textarea"
cols="30"
rows="10"
className={styles.textarea}
onChange={(e) => { this.handleChange('textarea', e) }} />
<div className={styles.con}>
篮球<input
type="checkbox"
name="sports"
value="篮球"
className={styles.checkbox}
onChange={(e) => { this.handleChange('sports', e) }} />
乒乓球<input type="checkbox"
name="sports" value="乒乓球"
className={styles.checkbox}
onChange={(e) => { this.handleChange('sports', e) }} />
排球<input type="checkbox"
name="sports" value="排球"
className={styles.checkbox}
onChange={(e) => { this.handleChange('sports', e) }} />
</div>
<div className={styles.con}>
A<input
type="radio"
name="words" value='A'
className={styles.radio}
onChange={(e) => { this.handleChange('words', e) }} />
B<input
type="radio"
name="words" value='B'
className={styles.radio}
onChange={(e) => { this.handleChange('words', e) }} />
C<input
type="radio"
name="words" value='C'
className={styles.radio}
onChange={(e) => { this.handleChange('words', e) }} />
</div>
<select
name="select"
value={select}
className={styles.select}
onChange={(e) => { this.handleChange('select', e) }}>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
<input
type="submit"
value="提交"
className={styles.submit} />
</form>
</div>
)
}
}
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 非受控组件
- 借助于 ref 就可以通过 非受控组件 的方式,来获取到的表单元素的值。
- ref 的作用:获取DOM对象或组件。
this.ref = React.createRef()
<input ref={this.ref} />
文本框的值:
this.ref.current.value
1
2
3
4
5
6
2
3
4
5
6