React Native 编码习惯带来的性能问题
React中当一个组件的属性发生变化时候,会触发该组件重新 render ,如果组件直接设置 props 为对象或数组,而两个对象或者两个数组比较是比较地址,即使内部数据是一致的,也会认为是不同的数据,组件会认为前后 props 不一致,重新 render 。
问题一:在设置一个组件 props 的时候直接设置对象
<TouchableOpacity
onPress={()=>{}}>
<Text>
登录
</Text>
</TouchableOpacity>
这是一个登录按钮,TouchableOpacity 的 onPress 中设置 {()=>{}} ,我们知道 {} === {} 结果是false,同样 funcation {()=>{}} === {()=>{}} 也是false。
解决方案
对于这样props我们可以在成员上使用箭头函数,在 onPress 中调用。
login = () => {
}
<TouchableOpacity
onPress={this.login}>
<Text>
登录
</Text>
</TouchableOpacity>
对于有些方法需要传参数,我们则可以采用 bind 的方式。
对于某些props已经带参数返回,我们则可以直接可以在成员上使用箭头函数并且直接调用参数,而不需要在使用bind方法。如TextInput的onChangeText,本身就带text返回。
onPhoneTextChange = (text) => {
this.loginPhone = text;
}
<TextInput
onChangeText={this.onPhoneTextChange}
/>
问题二:在设置一个组件 props 的时候直接设置对象或者数组
当我们需要给一个组件设置 style 的时候,有些时候我们会这样设置。
<View style={{flex:1}} />
或者
<View style={[styles.container,{backgroundColor: 'white'}]} />
解决方案
style 在 const styles = StyleSheet.create({}) 中统一赋值或者设置一个 相同引用的 style。
render() {
return (
<View style={styles.container}/>
)
}
const styles = StyleSheet.create({
container: {
flex:1,
backgroundColor: 'white'
},
});
或者
constructor(props) {
super(props);
this.containerStyle ={flex:1,backgroundColor:'white'};
}
render() {
return (
<View style={this.containerStyle}/>
)
}
总结
这些编码习惯都是直接设置props设置对象或数组带来性能损耗,而将这些数组或者对象保存成同一份引用,这样就能减少render。同时我们还可以使用 PureComponent 代替 Component ,减少 render 。
import React, {
PureComponent
} from 'react';
class Login extends PureComponent {
}
PureComponent 内部自带了实现了 shouldComponentUpdate,去判断这个组件是否是需要重新 render ,其实现的 shouldComponentUpdate 内部是一个浅比较。
import React, {
Component
} from 'react';
class Login extends Component {
shouldComponentUpdate(nextProps = {}, nextState = {}) {
return 浅比较(nextProps,this.props)|| 浅比较(nextState,this.state);
}
}
继承 PureComponent 和上述代码带来的功能是一样的。