React.PureComponent 与 React.Component 几乎相同
区别:
-
Component 中只要使用了setState,是否有更改,都会重新渲染组件(包括子组件),如需判断是否要重新渲染组件,需要借助shouldComponentUpdate
-
PureComponent 在原来Component 基础上自动添加了一个shouldComponentUpdate ,处理规则:对对象进行浅对比(指向地址变量,内容不变)
规则如下:
function isReset(obj1, obj2) {
if (
Object.keys(obj1).length !== Object.keys(obj2).length
) { return false }
for (let key in obj1) {
if (obj1[key] !== obj2[key]) {
return false
}
}
return true
}
Component 方式:
import React from 'react'
//浅比较:只比较地址
function isReset(obj1, obj2) {
if (
Object.keys(obj1).length !== Object.keys(obj2).length
) { return false }
for (let key in obj1) {
if (obj1[key] !== obj2[key]) {
return false
}
}
return true
}
export default class ComponentPure extends React.Component {
state = {
num: 0,
arr: [0, 1, 2]
};
handle = () => {
this.state.arr.push(3)
this.setState({
// arr: [...this.state.arr] //更改了地址,对应会重新渲染 console.log('是否更新'),并且组组件Small也会被渲染
arr: this.state.arr //地址没有更改,所以对应不会重新渲染
})
}
render() {
console.log('是否更新')
let { num } = this.state
return (
<button onClick={this.handle} ><Small num={num} />按钮</button>
)
}
shouldComponentUpdate(nextProps, nextState) {
return !isReset(this.state, nextState) || !isReset(this.props, nextProps)
}
}
class Small extends React.Component {
render() {
console.log('子组件是否更新')
return (
<div ></div >
)
}
}
PureComponent 方式
import React from 'react'
export default class ComponentPure2 extends React.PureComponent {
state = {
num: 0,
arr: [0, 1, 2]
};
handle = () => {
this.state.arr.push(3)
this.setState({
// arr: [...this.state.arr] //更改了地址,对应会重新渲染 console.log('是否更新2'),但Small组件没有改变所以不会重新渲染
arr: this.state.arr,//地址没有更改,所以不会重新渲染render,
})
}
render() {
console.log('是否更新2')
let { num } = this.state
return (
<button onClick={this.handle} ><Small num={num} />按钮</button>
)
}
}
class Small extends React.PureComponent {
render() {
const { num } = this.props
return (
<div >{num}</div >
)
}
}