ReactNative碎片整理之组件生命周期

生命周期是一定要知道的,这样才知道整个组件的工作流程,知道哪些操作适合在哪个回调中进行……(o^^o)

一个栗子

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
122
123
124
125
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet,
} from 'react-native';


export default class App extends Component<Props> {

/**
* 构造函数,初始化需要的state
* @param props
*/
constructor(props) {
super(props);

console.log('constructor')

// 初始状态
this.state = {
result: '点击前',
};
}

/**
* 描述:控件渲染前触发
* 次数:一次
* 推荐:
*/
componentWillMount() {
console.log('componentWillMount')
}

/**
* 描述:控件渲染后触发
* 次数:一次
* 推荐:
*/
componentDidMount() {
console.log('componentDidMount')
}

/**
* 描述:组件接收到新的props时被调用
* 次数:多次
* 推荐:
*/
componentWillReceiveProps() {
console.log('componentWillReceiveProps')
}

/**
* 描述:当组件接收到新的props和state时被调用
* 次数:多次
* 推荐:
*/
shouldComponentUpdate() {
console.log('shouldComponentUpdate')
return true;
}

/**
* 描述:组件重新渲染完成后会调用此方法
* 次数:多次
* 推荐:
*/
componentDidUpdate() {
console.log('componentDidUpdate')
}


/**
* 描述:控件渲染后触发
* 次数:1次
* 推荐:
*/
componentDidMount() {
console.log('componentDidMount')
}


/**
* 描述:组件卸载和销毁之前被调用
* 次数:一次
* 推荐:用于清理一些无用的内容,比如:定时器清除
*/
componentWillUnmount() {
console.log('componentWillUnmount')
}

componentWillUpdate() {
console.log('componentWillUpdate')
}
render() {
console.log('render')
return (
<View style={styles.content}>
<Text style={styles.text} onPress={
() => {
this.setState({
result: '点击后'
})
}
}>
{this.state.result}
</Text>
</View>
)
}
}

const styles = StyleSheet.create({
content: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
padding: 50,
fontSize: 20,
color: '#ffffff',
backgroundColor: '#00a056'
}
})

console

1
2
3
4
5
6
7
8
9
constructor
App.js:39 componentWillMount
App.js:103 render
App.js:86 componentDidMount
App.js:108 onPress call
App.js:66 shouldComponentUpdate
App.js:100 componentWillUpdate
App.js:103 render
App.js:76 componentDidUpdate

组件的生命周期

通过上面的栗子,有灵性的小哥哥已经基本猜到大致的生命周期了

下面再看看这张我偷来的帅图

再结合这张酷表

生命周期 调用次数 能否使用 setSate() 描述
getDefaultProps(es6:static defaultProps) 1(全局调用一次) 初始化默认属性
getInitialState(es6:constructor(props)) 1 构造函数,初始化需要的state
componentWillMount 1 控件渲染前触发
render >=1 渲染控件的方法
componentDidMount 1 控件渲染后触发
componentWillReceiveProps >=0 组件接收到新的props时被调用
shouldComponentUpdate >=0 当组件接收到新的props和state时被调用
componentWillUpdate >=0 props或者state改变,并且此前的shouldComponentUpdate方法返回为 true会调用该方法
componentDidUpdate >=0 组件重新渲染完成后会调用此方法

另外还有一个场景需要知道的,代码我就不贴了

父组件中有一个子组件,点击父组件调用setState,那么父子组件的生命周期如何回调?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//加载过程
constructor
App.js:42 componentWillMount
App.js:107 render
ChildComponent.js:26 ChildComponent,constructor
ChildComponent.js:41 ChildComponent,componentWillMount
ChildComponent.js:106 ChildComponent,render
ChildComponent.js:88 ChildComponent,componentDidMount
App.js:89 componentDidMount
//点击后,调用父组件的setState后
shouldComponentUpdate
App.js:103 componentWillUpdate
App.js:107 render
ChildComponent.js:59 ChildComponent,componentWillReceiveProps
ChildComponent.js:68 ChildComponent,shouldComponentUpdate
ChildComponent.js:102 ChildComponent,componentWillUpdate
ChildComponent.js:106 ChildComponent,render
ChildComponent.js:78 ChildComponent,componentDidUpdate
App.js:79 componentDidUpdate

可以看到:

  • 组件的加载是从内到外一级一级的,这个和android类似
  • 修改父组件state,触发update整个流程,但是不再次触发子组件的constructor

推荐的操作

  • constructor()方法里初始化state
  • static defaultProps指定默认属性
  • componentDidMount():该方法在render()方法后自动调用,网络请求一般放在这个方法中
  • shouldComponentUpdate():该方法返回一个boolean值,用来决定是否需要重新渲染组件,默认返回true,你可以自己重写此方法,通过条件判断来决定你是否需要更新组件
  • componentWillUnmount():在组件被移除前调用,在该方法中,释放一些不需要的资源,比如停止定时器
  • 不要在 constructor 或者 render 里 setState()
  • constructor 已含 this.state={}
  • render 里 setState 会造成setState -> render -> setState -> render
  • 能做的setState,只要是render前,就放在componentWillMount,render后,就放在 componentDidMount。這两个 function 是 react lifecycle 中,最常使用的两个
  • 更多以后再添加总结

补充

关于componentWillReceiveProps

componentWillReceiveProps:是在组件的props的更新的时,调用,那么有人就会有疑惑,组件的props不是不能改变的吗,只有state是可以改变的。注意,props确实不能修改的,指的是不能被自己修改,props是父组件传入进来的,在父组件首次render的时候,该方法不会被调用,那么由于父组件的State改变,render重新调用,传入子组件的props跟上次不同,那么这个方法就会被调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//父组件,有一个CommonButton的子组件,传入的props text的父组件的this.state.username
//首次render,CommonButton的
<View style={{marginTop: 15}}>
<CommonButton {...this.button} text={this.state.username} onPressFunc={this._onLogin}/>
</View>
//以下是子组件-CommonButton
//componentWillReceiveProps方法,在父组件,多次render会调用,我们一半先判断一下,和上次的是否相同,
//如果不相同,就设置子组件的state,让其更新
componentWillReceiveProps(nextProps) {
if(nextProps.text!==this.props.text){
this.setState({
text: nextProps.text
})
}
}

参考

React-Native生命周期的触发场景和一些小建议

React Native 中组件的生命周期

React Native之React速学教程(中)/)

文章目录
  1. 1. 一个栗子
  2. 2. 组件的生命周期
  3. 3. 推荐的操作
  4. 4. 补充
    1. 4.1. 关于componentWillReceiveProps
  5. 5. 参考