React - 如何用 useMemo 替换 useCallback 钩子?

React - how to replace useCallback hook with useMemo?

我正在阅读这篇关于 React 中的记忆的 article,我想知道如何翻译和使用 useMemo 而不是 useCallback 钩子。特别是对于这个例子:

<Child name={ useCallback(() => {console.log('Really Skinny Jack')}, [])  } />

子组件如下所示:

export default React.memo(function Child({ name }) {
  console.log("Child component");
  return (
    <>
      {name()}
      <div>Child component</div>
    </>
  );
});

如果我尝试将其替换为 useMemo:

  <Child
    name={useMemo(() => {
      console.log("useMemo");
    }, [])}
  />

我得到一个错误:

TypeError name is not a function

我也这样试过:

  {useMemo(
    <Child
      name={() => {
        console.log("useMemo");
      }}
    />,
    []
  )}

但是,然后我得到:

TypeError nextCreate is not a function

那么,在这个例子中,我该如何将 useCallback 替换为 useMemo

有了useMemo,你可以这样做

<Child
  name={useMemo(() => {
    // return the function or anything you want react to memoize
    return () => {
      console.log('useMemo');
    };
  }, [])}
/>

使用 useMemo,无论您从 useMemo 的回调中 return 做什么,都将被记忆。另一方面,useCallback 仅用于记忆功能。

需要注意的一些主要区别

useMemo

用于记忆函数、数组、对象等

const memoizedList = useMemo(() => {
  return [1, 2, 3];
}, []);

const memoizedFunction = useMemo(() => {
  return () => {
    console.log('I am meoized');
  };
}, []);

useCallback

用于记忆函数

const memoizedFunction = useCallback(() => {
  console.log('I am meoized');
}, []);

React.memo

一个 Higher-Order 用于记忆 React 组件的组件

const MyComponent = (props) => {
  return "I am a memoized component";
}
export default React.memo(MyComponent);

换成这样试试

<Child name={React.useMemo(() => () => alert(55), [])} />

So, I how am I suppose to replace useCallback with useMemo in this example?

useCallback 钩子 returns 传递给它的记忆回调函数,而 useMemo 钩子接受函数回调和 returns 记忆值。

来自 useCallback 文档:

useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).

以下是等效的实现:

  1. useCallback

    const nameHandler = useCallback(() => {
      console.log('Really Skinny Jack');
    }, []);
    ...
    <Child name={nameHandler} />
    
  2. useMemo

    const nameHandler = useMemo(() => () => {
      console.log('Really Skinny Jack');
    }, []);
    ...
    <Child name={nameHandler} />
    

useMemo 挂钩正在接受回调,即 returns 正在使用和传递的函数作为子组件的回调。

一点都不清楚为什么你会想要这样做。 useCallback 挂钩是当您想要记住传递给子组件的回调时要使用的预期挂钩。它也比 useMemo 版本中使用的“double”函数更清晰易读。我建议坚持使用代码的 useCallback 版本。