Skip to content

useMemoizedFn

useMemoizedFn 是持久化函数的 Hook,一般情况下,可以使用 useMemoizedFn 完全代替 useCallback,特殊情况见 FAQ

在某些场景中,我们需要使用 useCallback 来记住一个函数,但是在第二个参数 deps 变化时,会重新生成函数,导致函数地址变化。

类型声明

ts
declare function 
useMemoizedFn
<
T
extends
noop
>(
fn
:
T
):
T
;

源码

ts
import { 
useMemo
,
useRef
} from 'react';
import {
isFunction
} from '../utils';
import
isDev
from '../utils/isDev';
type
noop
= (
this
: any, ...
args
: any[]) => any;
type
PickFunction
<
T
extends
noop
> = (
this
:
ThisParameterType
<
T
>,
...
args
:
Parameters
<
T
>
) =>
ReturnType
<
T
>;
function
useMemoizedFn
<
T
extends
noop
>(
fn
:
T
) {
if (
isDev
) {
if (!
isFunction
(
fn
)) {
console
.
error
(`useMemoizedFn expected parameter is a function, got ${typeof
fn
}`);
} } const
fnRef
=
useRef
<
T
>(
fn
);
// why not write `fnRef.current = fn`? // https://github.com/alibaba/hooks/issues/728
fnRef
.
current
=
useMemo
<
T
>(() =>
fn
, [
fn
]);
const
memoizedFn
=
useRef
<
PickFunction
<
T
>>();
if (!
memoizedFn
.
current
) {
memoizedFn
.
current
= function (
this
, ...
args
) {
return
fnRef
.
current
.
apply
(this,
args
);
}; } return
memoizedFn
.
current
as
T
;
} export default
useMemoizedFn
;

FAQ

useMemoizedFn 返回的函数没有继承 fn 自身的属性?

useMemoizedFn 返回的函数与传入的 fn 的引用完全不同,且没有继承 fn 自身的属性。如果想要持久化后函数自身的属性不丢失,目前 useMemoizedFn 满足不了,请降级使用 useCallbackuseMemo

相关问题:#2273