React知识整理-生命周期
冰洋 1/11/2020 React
react从入门到放弃
# 旧版生命周期
# 1. 初始化
初始化属性props和状态state
constructor(props) {
super(props);
this.state = { number: 0 }
console.log('1.constructor构造函数')
}
1
2
3
4
5
2
3
4
5
# 2. 装载
//componentWillMount在渲染过程中可能会执行多次
componentWillMount() { // 取本地的数据 同步方式:采用渲染之前获取数据,只渲染一次
console.log('2.组件将要加载 componentWillMount');
}
render() {
console.log('3.render');
return (
<div>{this.state.number}</div>
)
}
// 只会执行一次
componentDidMount() {
console.log('4.组件挂载完成 componentDidMount');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3. 更新
属性更新props
componentWillReceiveProps(newProps) { // 第一次不会执行,之后属性更新时才会执行
console.log('1 componentWillReceiveProps')
}
// react可以shouldComponentUpdate方法中优化 PureComponent 可以帮我们做这件事
shouldComponentUpdate(nextProps, nextState) {
console.log('2 询问是否可以更新 shouldComponentUpdate')
return nextProps.n % 3 == 0; //子组件判断接收的属性 是否满足更新条件 为true则更新
}
componentWillUpdate() {
console.log('3 组件将要更新 componentWillUpdate');
}
render() {
console.log('4 render');
return (
<div>{this.props.number}</div>
)
}
componentDidUpdate() {
console.log('5 组件完成更新 componentDidUpdate');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
状态更新states
// 触发更新操作
handleClick = () => {
this.setState({ number: this.state.number + 1 });
};
// react可以shouldComponentUpdate方法中优化 PureComponent 可以帮我们做这件事
shouldComponentUpdate(nextProps, nextState): boolean { // 代表的是下一次的属性 和 下一次的状态
console.log('1 组件是否更新 shouldComponentUpdate');
return nextState.number % 2 == 0;
// return nextState.number!==this.state.number; //如果此函数种返回了false 就不会调用render方法了
} //不要随便用setState 可能会死循环
componentWillUpdate() {
console.log('2 组件将要更新 componentWillUpdate');
}
render() {
console.log('3 render');
return (
<div>{this.state.number}</div>
)
}
componentDidUpdate() {
console.log('4 组件完成更新 componentDidUpdate');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 4. 卸载
componentWillUnmount(){
console.log('组件卸载');
}
1
2
3
2
3
# 新版生命周期
- 去除三个生命周期:componentWillUpdate、componentWillMount、componentWillReceiveProps
- 新增:getDerivedStateFromProps、getSnapshotBeforeUpdate
# 1、getDerivedStateFromProps
根据传入的属性props派生到状态对象state 静态方法,必须加static
import React, { Component } from 'react'
export default class Counter extends Component {
constructor() {
super();
this.state = {number:0};
}
add = ()=>{
this.setState({number:this.state.number+1});
}
render() {
return (
<div>
<p>{this.state.number}</p>
<button onClick={this.add}>+</button>
<SubCounter number={this.state.number}/>
</div>
)
}
}
class SubCounter extends Component {
constructor(){
super();
this.state = {number:0};
}
//getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method
//根据新的属性对象派生状态对象 新的属性对象 和旧的状态对象
static getDerivedStateFromProps(nextProps,prevState){
if(nextProps.number%2==0){
return {number:prevState.number+nextProps.number*2};
}else{
return {number:prevState.number+nextProps.number*3};
}
}
render() {
return (
<div>
{this.state.number} {this.state.date}
</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
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
# 2、getSnapshotBeforeUpdate
获取更新前的快照,然后传递给componentDidUpdate的第三个参数。
import React, { Component } from 'react'
export default class GetSnapshotBeforeUpdate extends Component {
constructor(props){
super(props);
this.wrapper = React.createRef();
this.state = {messages:[]};
}
componentDidMount(){
setInterval(()=>{
this.setState({messages:["msg:"+this.state.messages.length,...this.state.messages]});
//this.setState({messages:[...this.state.messages,this.state.messages.length]});
},1000);
}
getSnapshotBeforeUpdate(){
//返回更新内容的高度 300px
return this.wrapper.current.scrollHeight;
}
//组件更新完毕
componentDidUpdate(prevProps,prevState,prevScrollHeight){
this.wrapper.current.scrollTop = this.wrapper.current.scrollTop+(this.wrapper.current.scrollHeight-prevScrollHeight);
}
render() {
let style = {
height:'100px',
width:'200px',
border:'1px solid red',
overflow:'auto'
}
return (
<ul style={style} ref={this.wrapper}>
{
this.state.messages.map((message,index)=><li key={index}>{message}</li>)
}
</ul>
)
}
}
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
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