网站首页 > 技术文章 正文
大家好,我是前端西瓜哥。
最近在尝试优化 React 组件,使用了 React.memo() 去缓存组件的渲染结果。
但有一个问题,就是要使 React.memo() 的缓存生效,需要保持 props 对象的浅比较结果为 true。
所以我们需要通过 useCallback 或 useMemo 处理一些对象类型的 prop,让它们保持指向原来的内存对象。
在 props 少的时候还好,但一旦多了之后,我们就比较难通过肉眼确认是哪个 prop 导致缓存失效。
怎样才能够方便地知道 props 的哪个属性发生了改变呢?
你可以试试 useWhyDidYouUpate。
useWhyDidYouUpate
useWhyDidYouUpate 是一个第三方 React Hooks,来自优秀的 ahooks 库。
名字很直白:Why did you update,意思就是 “你(组件)为什么更新了?”。
顾名思义,useWhyDidYouUpate 的作用是 帮助开发者排查是哪个属性改变导致了函数组件重渲染。
用法很简单,传入一个标识符字符串(通常为组件名)、以及要进行对比的对象(通常为 props)。
useWhyDidYouUpdate('Counter', props);
useWhyDidYouUpdate 会保存好上一次传入的 props,然后和新传入的 props 进行比较,找出不同的属性,将它们打印到控制台。
我们来看个示例:
import { useWhyDidYouUpdate } from 'ahooks';
import { useState } from 'react';
function Counter(props) {
useWhyDidYouUpdate('Counter', props);
return (
<div>
<div>{props.title}</div>
<div>{props.count}</div>
</div>
);
}
export default function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
<button onClick={() => setCount(count + 1)}>+ 1</button>
<Counter title={'计数显示'} count={count} />
</div>
);
}
点击 “+ 1” 按钮,然后就会在控制台看到下面输出:
这样我们就可以知道,是因为 count 从原来的 0,变成了现在的 1,导致了 Counter 组件的更新。
在线 demo:
https://codesandbox.io/s/u279ov?file=/src/App.js
实现
useWhyDidYouUpdate 的实现不是很复杂,我们直接贴源码(去掉 TS 类型标注)分析一下。
function useWhyDidYouUpdate(componentName, props) {
const prevProps = useRef({});
useEffect(() => {
if (prevProps.current) {
// 提取新旧 props 的属性,生成数组
const allKeys = Object.keys({ ...prevProps.current, ...props });
const changedProps = {};
allKeys.forEach((key) => {
// 对比 新旧 prop[key],如果不同,记录到对象中
if (!Object.is(prevProps.current[key], props[key])) {
changedProps[key] = {
from: prevProps.current[key],
to: props[key],
};
}
});
if (Object.keys(changedProps).length) {
// 输出到控制台
console.log('[why-did-you-update]', componentName, changedProps);
}
}
// 更新 prevProps
prevProps.current = props;
});
}
首先用 useRef 来声明一个 prevProps 变量,用来保存上一次的 props。
函数组件中,ref 可以实现类组件的实例属性的效果,确保每次渲染时可以保持原来的值。
然后将新旧 props 对象的属性提取出来,生成一个属性数组 allKeys。
遍历这个数组,去对比新旧 prop[key]。如果不同,记录到 changedProps 对象中。
最后输出改变的内容,并更新 prevProps。
结尾
当你尝试通过 React.memo() 给组件添加缓存时,却发现没能按照预期触发缓存,想要看看是哪个 props 发生了变化。
那么,你可以用 useWhyDidYouUpdate 来检查到底是哪些 prop 发生了改变。
当然不仅限于 props,我们也可以用 state 或其他对象上。
我是前端西瓜哥,欢迎关注我,学习更多前端知识。
- 上一篇: 移动端线上页面在没有开发者权限的情况下如何能转成pc端调试
- 下一篇: 在CLion中调试c语言
猜你喜欢
- 2024-11-19 记某次常规js前端逆向
- 2024-11-19 前端代码安全与混淆
- 2024-11-19 前端抓包神器--whistle
- 2024-11-19 使用chrome调试工具解决问题(六)
- 2024-11-19 使用chrome调试工具解决问题(七)
- 2024-11-19 使用chrome调试工具解决问题(五)
- 2024-11-19 使用chrome调试工具解决问题(四)
- 2024-11-19 使用chrome调试工具解决问题(三)
- 2024-11-19 楼宇自控系统设备的安装与调试
- 2024-11-19 使用chrome调试工具解决问题(一)
你 发表评论:
欢迎- 06-24发现一款开源宝藏级工作流低代码快速开发平台
- 06-24程序员危险了,这是一个 无代码平台+AI+code做项目的案例
- 06-24一款全新的工作流,低代码快速开发平台
- 06-24如何用好AI,改造自己的设计工作流?
- 06-24濮阳网站开发(濮阳网站建设)
- 06-24AI 如何重塑前端开发,我们该如何适应
- 06-24应届生靠这个Java简历模板拿下了5个offer
- 06-24服务端性能测试实战3-性能测试脚本开发
- 566℃Oracle分析函数之Lag和Lead()使用
- 564℃几个Oracle空值处理函数 oracle处理null值的函数
- 550℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 545℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 543℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 536℃【数据统计分析】详解Oracle分组函数之CUBE
- 526℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 518℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)