This gradual refining process is also the reason React apps are easy to optimize. If some parts of your component tree become too large for React to visit efficiently, you can tell it to skip this “refining” and diffing certain parts of the tree if the relevant props have not changed. It is very fast to calculate whether the props have changed if they are immutable, so React and immutability work great together, and can provide great optimizations with the minimal effort.
不可变值的目的就是就是为了提升性能。
同时 React.PureComponent 实现的是浅比较。
如果直接修改state,那么 React.PureComponent 就会失效。
class ListOfWords extends React.PureComponent {
render() {
return <div>{this.props.words.join(',')}</div>;
}
}
class WordAdder extends React.Component {
constructor(props) {
super(props);
this.state = {
words: ['marklar']
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// This section is bad style and causes a bug
const words = this.state.words;
words.push('marklar');
this.setState({words: words});
}
render() {
return (
<div>
<button onClick={this.handleClick} />
<ListOfWords words={this.state.words} />
</div>
);
}
The problem is that PureComponent will do a simple comparison between the old and new values of this.props.words. Since this code mutates the words array in the handleClick method of WordAdder, the old and new values of this.props.words will compare as equal, even though the actual words in the array have changed. The ListOfWords will thus not update even though it has new words that should be rendered.
# 浅比较
https://github.com/facebook/react/blob/master/packages/shared/shallowEqual.js https://github.com/facebook/react/blob/master/packages/shared/objectIs.js
其中is函数是自己实现的一个Object.is的功能,排除了===两种不符合预期的情况:
+0 === -0 // true,但我们期待返回false
NaN === NaN // false,但我们期待返回true
shallowEqual函数完成的功能:
- 通过is函数对两个参数进行比较,判断是否相同,相同直接返回true:基本数据类型值相同,或者是同一个引用对象;
- 如果两个参数不相同,判断两个参数是否至少有一个不是引用类型,存在即返回false,如果两个都是引用类型对象,则继续下面的比较;
- 判断两个不同引用类型对象是否相同:先通过Object.keys获取到两个对象的所有属性,具有相同属性,且每个属性值相同即两个对象相同(相同也通过is函数成)