减少render次数
- 使用PureComponent,默认实现了shouldComponentUpdate方法,对state对象进行了浅比较。
- 但如果state为复杂的数据结构,需小心setState可能会导致组件未被重新渲染。
- PureComponent适用于一些state数据结构简单的组件,对于复杂的数据结构,如果使用了PureComponent,最好结合forceUpdate来使用,防止state改变了,但未被刷新。但这样使用PureComponent的意义就不大了。
import React from 'react';
import ReactDOM from 'react-dom';
class Index extends React.PureComponent {
state = {
data: {
count: 1
}
}
onClickBtn = () => {
const data = this.state.data;
data.count = 10;
console.log(data);
this.setState({
data: data
});
this.forceUpdate();
}
render() {
console.log('render...');
return <>
<p>{this.state.data.count}</p>
<button onClick={this.onClickBtn}>add</button>
</>;
}
}
ReactDOM.render(<Index />, document.getElementById('root'));
- 如果state为复杂的数据结构,但又想提升性能,可以结合immutable的equals快速对比数据的变化
import React from 'react';
import ReactDOM from 'react-dom';
import { Map } from 'immutable';
class Index extends React.Component { // 如果使用了shouldComponentUpdate,不推荐使用PureComponent,会被警告
state = {
data: Map({
count: 1
})
}
shouldComponentUpdate(nextProps, nextState) {
if(this.state.data.equals(nextState.data)){ // 利用immutable的equals,可以快速比较复杂的数据是否发生了变化
return false;
}
return true;
}
onClickBtn = () => {
this.setState({
data: Map({
count: 1
})
});
}
render() {
console.log('render...');
return <>
<p>{this.state.data.get('count')}</p>
<button onClick={this.onClickBtn}>add</button>
</>;
}
}
ReactDOM.render(<Index />, document.getElementById('root'));
- 对于函数组件,可以使用React.memo生成高阶组件,此高阶组件默认会对props进行浅比较,从而决定是否要更新组件。
import React, { Component } from "react";
import ReactDom from "react-dom";
const Child = (props) => {
console.log("child render....");
return <p>{props.t}</p>;
};
const ChildMemo = React.memo(Child);
class Index extends Component {
state = {
t: 1
}
clickBtn = () => {
this.setState(state => ({
t: state.t
}))
}
render() {
return (
<>
<button onClick={this.clickBtn} >click</button>
<ChildMemo t={this.state.t} />
</>
);
}
}
ReactDom.render(<Index />, document.getElementById("root"));
网友评论