发布时间:2019年3月3日
该篇文章为2019年初在政采云内部做的React优化分享,可能存在过时内容
import React, { Component } from 'react';
import PureTest from './pureComp';
const titleArr = ['第一个标题', '第二个标题', '第三个标题'];
class PureComp extends Component {
state = {
title: '第一个标题',
}
componentDidUpdate() {
console.log(`父组件更新,标题为${this.state.title}`);
}
handleClick = () => {
this.setState({
title: titleArr[Math.round(Math.random() * 2)],
});
}
render() {
const { title } = this.state;
return (
<div>
<button onClick={this.handleClick.bind(this)}>更改state</button>
<PureTest title={title} />
</div>
);
}
}
export default PureComp;
import React, { PureComponent } from 'react';
class PureTest extends PureComponent {
componentDidUpdate() {
console.log(`pureComponent组件更新,标题为${this.props.title}`);
}
render() {
return (
<h1>{this.props.title}</h1>
);
}
}
export default PureTest;
基于这个特性我们应该避免在中引用纯组件时写出如下代码
// 避免写{}作为默认值,因为每次使用{}时指向的内存地址都不一样,在浏览器控制台中输入{}==={}就可以看到返回值为false <PureTestComp value={this.state.pureObj || {}} /> // 有时候为了提高程序的健壮性,我们必须写默认值,那么就将默认值抽出来做一个单独的变量 const defaultEmpty = {}; <PureTestComp value={this.state.pureObj || defaultEmpty} />
总结及注意事项
其实pureComponent组件还会判断state是否发生了变动,但是在我看来使用pureComponent的场景在于纯展示组件,且传递的props数据层级也应该尽可能的浅,不建议在pureComponent维护一套state,具体的shallowEqual算法如下
if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps)
|| !shallowEqual(inst.state, nextState);
}
React.memo适用于函数式组件,相当于一个高阶函数,将普通的函数式组件包装成一个类似pureComponent的组件,React.memo接受两个参数
使用过shouldComponentUpdate的同学可以注意到了第二个回调函数的返回值和shouldComponentUpdate是相反的,在回调函数中如果title相同时返回true,而不同时返回fasle,似乎与我们理解的不同。
其实这个问题在于我们对areEquals这个值的理解,在shouldComponentUpdate我们返回的是要不要更新,而areEqulas值的意思为是不是相同的,在相同时即为true时我们不更新,在不同时即为fasle时我们更新组件,也就是说第二个回调函数其实也可以理解为是一个shouldComponentNotUpdate生命周期