Search code examples
reactjsreact-hooks

React - how to replace useCallback hook with useMemo?


I am reading this article about memoization in React, and I wonder how can I translate and use useMemo instead of useCallback hook. In particular for this example:

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

Where Child component looks like this:

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

If I try to replace this with useMemo:

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

I get an error:

TypeError name is not a function

I also tried like this:

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

But, then I get:

TypeError nextCreate is not a function

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


Solution

  • With useMemo, you can do it like this

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

    With useMemo, whatever you return from the useMemo's callback will be memoized. On the other hand, useCallback is used to memoize functions only.

    Some key differences to note

    useMemo

    Used to memoize functions, arrays, objects, etc.

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

    useCallback

    Used to memoize functions

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

    React.memo

    A Higher-Order Component to memoize React components

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