⽗组件调⽤⼦组件中的⽅法_react⽗组件重绘导致⼦组件做没
有必要的重绘
react组件的重复渲染是导致react性能下降的⼀个原因,接下来我们来具体分析⼀下⽗组件重绘导致⼦组件出现没有必要重绘的情况。
⾸先我们应该有⼀个⽗组件
export default class LifecycleScreenExample extends React.Component {
constructor(props) {
super(props);
this.state = { text: '点击按钮' };
}
render() {
console.log();
return (
<View>
<TouchableOpacity onPress={this.changeText}>
<Text>{}</Text>
</TouchableOpacity>
<One />
<Two />
</View>
);
}
changeText = () => this.setState({ text: '按钮被点击了' });
}
根据⽗组件,我们应该还有两个⼦组件,分别是One和Two
export default class One extends React.Component {
render() {
console.log('---one render-------');
react组件之间通信return (
<View>
<Text>component one</Text>
</View>
);
}
}
export default class Two extends React.Component {
render() {
console.log('---two render-------');
return (
<View>
<Text>component two</Text>
</View>
);
}
}
此时⽗组件点击⽗组件的按钮,我们想要的结果是⽗组件中按钮⽂字改变,⼦组件并不受到影响,不会 render。但是事实上是⽗组件中按钮⽂字确实改变了,与此同时⼦组件也重新render了,这并不是我们想要的。
协调(Reconciliation)进⾏diff算法,⽗组件
从 react 的⽂档上我们能看到,调⽤setState后,react会执⾏ 协调(Reconciliation)
LifecycleScreenExample 需要重新渲染,所以⼦组件也需要重新渲染。我们可以通过 pureComponent 或者shouldComponentUpdate ⽣命周期函数避免重复渲染。
我们可以看⼀下修改过后的⼦组件,以及修改过后的结果
export default class One extends React.PureComponent {
render() {
console.log('---one render-------');
return (
<View>
<Text>component one</Text>
</View>
);
}
}
export default class Two extends React.PureComponent {
render() {
console.log('---two render-------');
return (
<View>
<Text>component two</Text>
</View>
);
}
}
能够看到修改过后,⽗组件的重新渲染并没有引起⼦组件的⽆畏重绘,达到了我们的⽬的。或者我们也可以在 shouldComponentUpdate ⽣命周期中做⽐较,也能避免重绘。接下来聊⼀下 PureComponent 做了什么操作让我们达成了⽬的。
PureComponent
⾸先我们来看⼀下 PureComponent 的源码。
可以看到 PureComponent 的使⽤⽅式和 Component ⼀致,只时为其添加了⼀个 isPureReactComponent 属性。ComponentDummy 就是通过原型继承的⽅式将 Component 原型中的⽅法和属性传递给了 PureComponent。我们从PureComponent 的源码中能得到这些信息。接下来我们再看 React 源码中这样⼀个函数
在检查组件是否更新的函数中,我们能看到,如果判断组件原型上 isPureReactComponent 属性为 true,那么就对组件的 props 和state 做 shallowEqual ⽅法的⽐较。继续看 shallowEqual 的源码,看看它⼲了什么事?
通过 is ⽅法判断基本属性类型值是否相同(包括 NaN),引⽤数据类型是否是⼀个引⽤,如果是返回 true;
newProps(newState) 和 oldProps(oldState) 任意⼀个不是 object 或者 任意⼀个为 null,直接返回 false,如果为 true 表⽰⼆者都是 object;
⼆者都为object,⽐较它们的 key 的数量是否⼀致,如果不⼀致返回 false;
如果 key 的数量不⼀致,则对两个对象中的第⼀层属性进⾏⽐较,若都相同,则返回 true,有任⼀属性不同,则返回 false
最后,再根据 checkShouldComponentUpdate ⽅法中的判断,如果 props 和 state 的shallowEqual ⽐较结果都为 true 表⽰组件不需要重新渲染,如果其中有⼀个为 false 表⽰组件需要重新渲染。
这⾥有⼏点需要注意的
这⾥的 shallowEqual ⽐较只是浅⽐较,适⽤于原始数据类型的⽐较,对引⽤数据类型超过⼀层就会不准
在 react-redux 中的 connect ⽅法也使⽤的 shallowEqual 做的浅⽐较
如果希望对层级较深的对象做⽐较的话,可以使⽤ shouldComponentUpdate ⽣命周期来进⾏⽐较,但是需要配合 immutable 持久
化数据结构来使⽤达到最好效果

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。