React-Native优化之PureComponent

React15.3的发布中包含了PureComponent,这个类最重要的用法是为了优化React的性能,下面我们将看下它是如何优化的。

Component VS PureComponent

首先要看Component的生命周期:

当props或者state改变的时候,会执行shouldComponentUpdate方法来判断是否需要重新render组建,我们平时在做页面的性能优化的时候,往往也是通过这一步来判断的。Component默认的shouldComponentUpdate返回的是true,如下:

1
2
3
shouldComponentUpdate(nextProps, nextState) {
return true;
}

而PureComponent的shouldComponentUpdate是这样的:

1
2
3
if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps) || ! shallowEqual(inst.state, nextState);
}

这里的比较,只会做潜比较,即比较两者的内存地址是否相同,而对于其值是否发生变化,则不会理会。我们通过以下的例子来看下:

例子

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
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { PureComponent,Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Button
} from 'react-native';
export default class test extends PureComponent {
constructor(props){
super(props);
this.state = {
number : 1,
numbers: [],
};
}
render() {
return (
<View style={styles.container}>
<Button title={'number + 1'} onPress={this.numberAdd.bind(this)} />
<Text>number value: {this.state.number}</Text>
<Button title={'numbers + 1'} onPress={this.numbersAdd.bind(this)} />
<Text>numbers length: {this.state.numbers.length}</Text>
</View>
);
}
numberAdd(){
this.setState({number: ++this.state.number });
}
numbersAdd(){
let numbers = this.state.numbers;
numbers.push(1);
this.setState({numbers: numbers});
console.log(this.state.numbers);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('test', () => test);

界面如下:

这里去点击number+1 和 numbers+1都不会有任何页面的变化。

如何让PureComponent重绘

那如果PureComponent变化的时候(这其实不符合我们的初衷),我们要怎么做呢?这里有两个办法:

  1. 重写shouldUpdateComponent方法
  2. props或者state增减参数

代码如下:

1
2
3
4
5
6
7
8
numbersAdd(){
let numbers = this.state.numbers;
numbers.push(1);
this.setState({numbers: numbers});
console.log(this.state.numbers);
this.setState({newState: 1});
}

这样,shouldComponentUpdate的返回值也会是true。

总结

综上,PureComponent非常适合于不变的组件,尤其是和数据、业务无关的纯展示组件,因为它的节省了大量比较的工作。但是对于大部分的业务来说,界面很少会有不变的组件,所以使用的场景会比较少,但是如果遇到,请尽情使用!