shouldComponentUpdate
2024年03月06日
一、认识
shouldComponentUpdate
当组件接收到新的 props
或调用 setState
更新 state
后,shouldComponentUpdate
会在渲染过程开始前被调用。根据返回值来决定是否需要渲染: 返回 true
, 组件将继续更新, 调用 render
生成新的虚拟 DOM
, 并最终提交到页面; 返回 false
, 组件将跳过此次更新, render
不会被调用,组件保持当前状态和 UI
不变。这个方法应该是纯函数,即不能产生副作用,且只依据新旧 props
和 state
做比较,返回一个布尔值。一般情况,不建议在该周期方法中进行深层比较,会影响效率, 同时也不能调用 setState
,否则会导致无限循环调用更新。需要重点关注的是第二个参数 newState
,如果有 getDerivedStateFromProps
生命周期 ,它的返回值将合并到 newState
,供 shouldComponentUpdate
使用。
二、语法
shouldComponentUpdate(newProps,newState){
if(newProps.a !== this.props.a ){ /* props中a属性发生变化 渲染组件 */
return true
}else if(newState.b !== this.props.b ){ /* state 中b属性发生变化 渲染组件 */
return true
}else{ /* 否则组件不渲染 */
return false
}
}
三、场景
3.1 比较基础数据,控制渲染
比较基础数据,控制渲染: 可以直接比较前后数据是否相等
import React, { Component } from "react";
import ReactDOM from "react-dom";
class App extends Component {
constructor(props) {
super(props);
this.state = {
num: 0,
};
}
handleClick() {
this.setState({
num: this.state.num + 1,
});
}
shouldComponentUpdate(newProps, newState) {
if (newState.num !== this.state.num) {
return true;
}
return false;
}
render() {
const { num } = this.state;
return (
<div>
<h3>App 组件</h3>
{num}
<button onClick={() => this.handleClick()}>改变</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
3.2 比较引用数据,控制渲染
比较引用数据,控制渲染: 不可以直接比较是否相等,需要借助 immutable.js
来对比
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Immutable from "immutable";
class App extends Component {
constructor(props) {
super(props);
this.state = {
like: Immutable.Map({ a: 1, b: 2, c: 3 }),
};
}
handleClick() {
this.setState({
like: Immutable.Map({ a: 2, b: 2, c: 3 }),
});
}
shouldComponentUpdate(newProps, newState) {
if (Immutable.is(newState.like,this.state.like)) {
console.log('kk')
return true;
}
return false;
}
render() {
const { like } = this.state;
return (
<div>
<h3>App 组件</h3>
{like.get('a')}
<button onClick={() => this.handleClick()}>改变</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));