如何复用PureComponent的浅比较逻辑自定义shouldComponentUpdate?
解决方案:复用PureComponent浅比较逻辑的正确方式
我完全理解你的需求——想做一个能通过特定属性控制是否更新的组件,平时复用PureComponent的浅比较逻辑,只有当指定属性为true时才阻止更新。你遇到的super.shouldComponentUpdate未定义的问题,其实是因为PureComponent的shouldComponentUpdate逻辑是React内部实现的,并没有暴露成可直接调用的实例方法,它不是挂载在原型链上供我们通过super调用的,所以访问不到是正常的。
不用自己手写复杂浅比较的话,有个很稳妥的办法:使用和React PureComponent逻辑完全一致的现成浅比较工具函数,在自定义的shouldComponentUpdate里组合你的控制逻辑和浅比较。
具体实现步骤
- 可以直接使用
react-redux包提供的shallowEqual函数(它的逻辑和PureComponent用的浅比较完全一致,无需自己实现);如果你的项目里没有react-redux,也可以直接复刻React内部的浅比较逻辑(代码很简单,不算“自行编写复杂逻辑”)。 - 继承PureComponent,重写
shouldComponentUpdate:- 先判断你的控制属性(比如叫
preventUpdate),如果为true,直接返回false阻止更新; - 否则,用
shallowEqual对比当前和下一个props、state,返回对比结果(和PureComponent的默认逻辑一致)。
- 先判断你的控制属性(比如叫
代码示例(依赖react-redux的shallowEqual)
import React, { PureComponent } from 'react'; import { shallowEqual } from 'react-redux'; class ControllablePureComponent extends PureComponent { shouldComponentUpdate(nextProps, nextState) { // 当preventUpdate为true时,阻止组件更新 if (this.props.preventUpdate) { return false; } // 复用PureComponent的浅比较逻辑 return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); } render() { return ( <div> {/* 你的组件内容 */} {this.props.children} </div> ); } }
不依赖第三方包的替代方案(复刻React浅比较逻辑)
如果不想引入react-redux,可以把这个和React一致的浅比较函数放在项目工具库中复用:
function shallowEqual(objA, objB) { if (Object.is(objA, objB)) { return true; } if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { return false; } const keysA = Object.keys(objA); if (keysA.length !== Object.keys(objB).length) { return false; } for (const key of keysA) { if (!Object.prototype.hasOwnProperty.call(objB, key) || !Object.is(objA[key], objB[key])) { return false; } } return true; }
之后在组件里直接调用这个函数即可,逻辑和PureComponent完全一致。
内容的提问来源于stack exchange,提问作者corvid
相关产品推荐
相关产品推荐

