当前位置:网站首页>useMemo模拟useCallback
useMemo模拟useCallback
2022-06-25 06:39:00 【CamilleZJ】
useMemo缓存结果,useCallback缓存函数
1、看一下useMemo和useCallback底层源码的区别
useMemo 源码实现
组件首次渲染时 useMemo 的源码实现:
// React 版本:16.13.1
// react-reconciler/src/ReactFiberHooks.new.js
function mountMemo<T>(
nextCreate: () => T, // “创建”函数
deps: Array<mixed> | void | null, // 依赖项
): T {
const hook = mountWorkInProgressHook();
const nextDeps = deps === undefined ? null : deps;
const nextValue = nextCreate(); // 执行 "创建"函数
hook.memoizedState = [nextValue, nextDeps]; // 将 "创建"函数 执行后的返回值缓存起来
return nextValue; // 返回缓存后的变量值
}
useMemo 的依赖项发生变化时useMemo的源码实现:
// React 版本:16.13.1
// react-reconciler/src/ReactFiberHooks.new.js
function updateMemo<T>(
nextCreate: () => T,
deps: Array<mixed> | void | null,
): T {
const hook = updateWorkInProgressHook();
const nextDeps = deps === undefined ? null : deps;
const prevState = hook.memoizedState;
if (prevState !== null) {
// Assume these are defined. If they're not, areHookInputsEqual will warn.
if (nextDeps !== null) {
const prevDeps: Array<mixed> | null = prevState[1];
if (areHookInputsEqual(nextDeps, prevDeps)) {
return prevState[0];
}
}
}
const nextValue = nextCreate();
hook.memoizedState = [nextValue, nextDeps];
return nextValue;
}依赖对比:
function areHookInputsEqual(nextDeps, prevDeps) {
if (prevDeps === null) {
{
warning$1(false, '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
}
return false;
}
{
// Don't bother comparing lengths in prod because these arrays should be
// passed inline.
if (nextDeps.length !== prevDeps.length) {
warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, '[' + nextDeps.join(', ') + ']', '[' + prevDeps.join(', ') + ']');
}
}
for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
if (is(nextDeps[i], prevDeps[i])) {
continue;
}
return false;
}
return true;
}
/**
* inlined Object.is polyfill to avoid requiring consumers ship their own
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
function is(x, y) {
return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
;
}注意:上面react包括state和props对比都是采用shallowEaque,只比较一层。且依赖是对象时X===Y不同对象即使内容一样仍然return false,如下案例,除非前两种useMemo才不会更新,否则每次都更新,useEffect及useCallback同理,useMemo常用来缓存组件,所以不要乱用useMemo等hooks
const [obj, setObj] = useState({a:1})
//如点击等导致state更新
setObj(obj)
setObj(preObj=>preObj)
setObj(preObj=>{...preObj})
useMemo(()=>{....},[obj]useCallback 源码实现
组件首次渲染时 useCallback 的源码实现:
// React 版本:16.13.1
// react-reconciler/src/ReactFiberHooks.new.js
function mountCallback<T>(callback: T, deps: Array<mixed> | void | null): T {
const hook = mountWorkInProgressHook();
const nextDeps = deps === undefined ? null : deps;
hook.memoizedState = [callback, nextDeps];
return callback;
}
useCallback 的依赖项发生变化时useMemo的源码实现:
// React 版本:16.13.1
// react-reconciler/src/ReactFiberHooks.new.js
function updateCallback<T>(callback: T, deps: Array<mixed> | void | null): T {
const hook = updateWorkInProgressHook();
const nextDeps = deps === undefined ? null : deps;
const prevState = hook.memoizedState;
if (prevState !== null) {
if (nextDeps !== null) {
const prevDeps: Array<mixed> | null = prevState[1];
if (areHookInputsEqual(nextDeps, prevDeps)) {
return prevState[0];
}
}
}
hook.memoizedState = [callback, nextDeps];
return callback;
}useMemo 和 useCallback 都是返回一个缓存后的值,useMemo 返回的是一个缓存后的变量,而useCallback 返回的是一个缓存后的回调函数。可以在 useMemo 的 "创建函数" 中返回一个回调函数来模拟 useCallback 的功能。useMemo 和 useCallback 可以用来解决函数组件更新过程中的性能问题。
// 使用 useCallback 缓存函数
const addClick = useCallback(() => {
let sum = 0;
for (let i = 0; i < count; i++) {
sum += i;
}
return sum;
}, [count]);
// 使用 useMemo替代useCallback 缓存函数
const addClick = useMemo(() => () => {
let sum = 0;
for (let i = 0; i < count; i++) {
sum += i;
}
return sum;
}, [count]);
边栏推荐
- Research on 3D model retrieval method based on two channel attention residual network - Zhou Jie - paper notes
- 三年营收连续下滑,天地壹号困在醋饮料里
- STL教程4-输入输出流和对象序列化
- ELK + filebeat日志解析、日志入库优化 、logstash过滤器配置属性
- 几款不错的天气插件
- Common functions of OrCAD schematic
- Mysql database import SQL file display garbled code
- 【LeetCode】two num·两数之和
- 【批处理DOS-CMD命令-汇总和小结】-添加注释命令(rem或::)
- 【批处理DOS-CMD命令-汇总和小结】-文件与目录操作命令(md、rd、xcopy、dir、cd、set、move、copy、del、type、sort)
猜你喜欢

Shell tips (134) simple keyboard input recorder

三年营收连续下滑,天地壹号困在醋饮料里

PI Ziheng embedded: This paper introduces the multi-channel link mode of i.mxrt timer pit and its application in coremark Test Engineering

栅格地图(occupancy grid map)构建

Modular programming of digital light intensity sensor module gy-30 (main chip bh1750fvi) controlled by single chip microcomputer (under continuous updating)

VectorDraw Web Library 10.10

韩信大招:一致性哈希

Don't you know the evolution process and principle of such a comprehensive redis cluster model?

Genuine photoshop2022 purchase experience sharing

Intel announced five new technological developments, including quantum computing, neural pseudo computing, machine programming, integrated optoelectronics, and secure computing
随机推荐
【批处理DOS-CMD命令-汇总和小结】-cmd扩展命令、扩展功能(cmd /e:on、cmd /e:off)
Notes: [open class] neural network and deep learning -- tensorflow2.0 actual combat [Chinese course]
Kube scheduler source code analysis (1) - initialization and startup analysis
Chang Wei (variables and constants) is easy to understand
Display purchase Summary - Dell 2705qm BenQ pd2700u
[batch dos-cmd command - summary and summary] - commands related to Internet access and network communication (Ping, Telnet, NSLOOKUP, ARP, tracert, ipconfig)
13 `bs_ duixiang. Tag tag ` get a tag object
Alphassl wildcard certificate for one month
Large funds support ecological construction, and Plato farm builds a real meta universe with Dao as its governance
我的处女作杀青啦!
Enter an integer with any number of bits, and output the sum of each bit of the number. For example: 1234 – > 10
用动图讲解分布式 Raft
[batch dos-cmd command - summary and summary] - file and directory operation commands (MD, RD, xcopy, dir, CD, set, move, copy, del, type, sort)
Harmony food menu interface
How is the network connected?
Ltpowercad II and ltpowerplanner III
Intel announced five new technological developments, including quantum computing, neural pseudo computing, machine programming, integrated optoelectronics, and secure computing
[batch dos-cmd command - summary and summary] - CMD extended command and function (CMD /e:on, CMD /e:off)
smartBugs安装小问题总结
Cocos学习日记3——api获取节点、组件