【笔记】React的组件

前言

React的组件学习笔记

类组件(Class Component)

定义组件

  • 组件名首字母大写
  • 必须继承React.Component
  • 必须重写render()方法,并返回React组件对象
    • 每个React组件只能由一个根组件构成,组件内可以包含任意数量的子组件
    • return可以返回的数据类型
      • 返回React组件对象,渲染为DOM
        • 每当使用return返回组件时,推荐使用()进行包裹,便于与原始JS代码区分
      • 返回字符串或数值类型数据,直接渲染
      • 返回null或布尔类型数据,不渲染任何内容
      • 返回数组或fragments
      • 返回Portals
  • 使用组件时,既可以使用单标签引入,也可以使用双标签引入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Component extends React.Component {

...

render() {
return (
<>
...
</>
);
}
}

export default Component;

定义组件的实例方法

  • render()中使用实例方法时,需要重新绑定this,才能在实例方法中使用this

只有event参数的情况

  • 在构造方法中统一为实例方法绑定this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Component extends React.Component {

constructor() {
super();

this.fn = this.fn.bind(this);
}

fn(event) {
...
}

render() {
return (
<>
<div onClick={ this.fn }></div>
</>
);
}
}
  • 在传递实例方法时绑定this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Component extends React.Component {

fn(event) {
...
}

render() {
return (
<>
<div onClick={ this.fn.bind(this) }></div>
</>
);
}
}
  • 不使用实例方法,改为使用实例属性,并且属性值是箭头函数定义的函数,这种方式无需显式绑定this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Component extends React.Component {

fn = (event) => {
...
}

render() {
return (
<>
<div onClick={ this.fn }></div>
</>
);
}
}
  • 不使用实例方法,改为直接使用箭头函数,箭头函数执行需要调用的实例方法,这种方式无需显示绑定this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Component extends React.Component {

fn = (event) => {
...
}

render() {
return (
<>
<div onClick={ (event) => this.fn(event) }></div>
</>
);
}
}

除了event参数还包含其他自定义参数的情况

  • 在传递实例方法时绑定this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Component extends React.Component {

fn(arg, event) {
...
}

render() {
return (
<>
<div onClick={ this.fn.bind(this, "value") }></div>
</>
);
}
}
  • 不使用实例方法,改为直接使用箭头函数,箭头函数执行需要调用的实例方法,这种方式无需显示绑定this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Component extends React.Component {

fn = (event, arg) => {
...
}

render() {
return (
<>
<div onClick={ (event) => this.fn(event, "value") }></div>
</>
);
}
}

组件的状态

定义组件的状态

渲染值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Component extends React.Component {

constructor() {
super();

this.state = {
key: "value"
};
}

render() {
return (
<>
<div>{ this.state.key }</div>
</>
);
}
}
渲染数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Component extends React.Component {

constructor() {
super();

this.state = {
key: []
};
}

render() {
return (
<>
<ul>{ this.state.key.map(item -> <li>{ item }</li>) }</ul>
</>
);
}
}

修改组件的状态

  • 通过this.setState()在组件的实例方法中修改组件的状态
    • 通过this.setState()修改组件的状态时,只会修改实参对象中定义的属性,而不会覆盖其他属性
    • 通过this.setState()修改组件的状态完成后,会自动执行render()重新渲染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
25
26
class Component extends React.Component {

constructor() {
super();

this.state = {
key: "default"
};

this.fn = this.fn.bind(this);
}

fn() {
this.setState({
key: "value"
});
}

render() {
return (
<>
<div onClick={ this.fn }>{ this.state.key }</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
class Component extends React.Component {

constructor() {
super();

this.state = {
obj: {
key: "default"
}
};

this.fn = this.fn.bind(this);
}

fn() {
const copyObj = Object.assign(new Object(), originalObj);
copyObj.key = "value";
this.setState({
obj: copyObj
});
}

render() {
return (
<>
<div onClick={ this.fn }>{ this.state.obj.key }</div>
</>
);
}
}

生命周期函数

  • 组件挂载:constructor()创建组件实例=>getDevicedStateFromProps()=>render()重新渲染虚拟DOM=>渲染真实DOM=>componentDidMount()完成组件挂载
  • 组件更新:getDevicedStateFromProps()=>shouldComponentUpdate()预检查是否更新,如果返回false就不更新=>render()重新渲染虚拟DOM=>getSnapshopBeforeUpdate()=>componentDidUpdate(prevProps, prevState, snapshot)完成组件更新
  • 组件卸载:componentWillUnmount()完成组件卸载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Component extends React.Component {
constructor() {
super();
}
render() {
...
};
conponentDidMount() {
...
};
componentDidUpdate(prevProps, prevState, snapshot) {
...
};
componentWillUnmount() {
...
};
shouldComponentUpdate() {
...
}
getSnapshopBeforeUpdate() {
...
}
}

函数式组件(Functional Component)

定义组件

  • 组件名首字母大写
  • return可以返回的数据类型,与类组件相同
1
2
3
4
5
6
7
8
9
10
11
12
function Component() {

...

return (
<>
...
</>
);
}

export default Component;

完成