Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between useCallback and useRef hooks when useRef is used as an instance variable

I'm reading about hooks in React, and I have some trouble understanding the difference between useRef and useCallback hooks.

Specifically, I'm looking to understand how these two can be used to avoid unnecessary re-renders of child components.

Based on my understanding of this answer on stack overflow, the following function can be written as:

  const Avatar = function({ history, url, fullName }) {
  const onMenuItemClick = urlToNavigate => history.push(urlToNavigate),
    onMenuItemClickRef = useRef(onMenuItemClick);

  return (
    <Menu
      label={<RoundedImage src={url} alt={fullName} />}
      items={[
        { label: `Logged in as: ${fullName}` },
        {
          label: "Liked articles",
          onClick: () => onMenuItemClickRef.current("/liked-articles")
        },
        {
          label: "Edit profile",
          onClick: () => onMenuItemClickRef.current("/profile")
        },
        { label: "Logout", onClick: () => console.log("Logging out") }
      ]}
    />
  );
};

Would it also make sense to replace:

const onMenuItemClick = urlToNavigate => history.push(urlToNavigate)

with:

const onMenuItemClick = useCallBack(urlToNavigate => history.push(urlToNavigate), [urlToNavigate])

so it changes only when urlToNavigate changes?

like image 777
sotiristherobot Avatar asked Sep 10 '19 12:09

sotiristherobot


People also ask

For what purpose is the useCallback () hook used?

The useCallback hook is used when you have a component in which the child is rerendering again and again without need. Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed.

What is useRef hook and why it is used?

The useRef Hook allows you to persist values between renders. It can be used to store a mutable value that does not cause a re-render when updated. It can be used to access a DOM element directly.

What is the difference between useMemo and useCallback hook?

useMemo is very similar to useCallback. It accepts a function and a list of dependencies, but the difference between useMemo and useCallback is that useMemo returns the memo-ized value returned by the passed function. It only recalculates the value when one of the dependencies changes.

Is useRef a hook?

useRef(initialValue) is a built-in React hook that accepts one argument as the initial value and returns a reference (aka ref).


1 Answers

In the link you reference in your question the key is that the children component (the one that receives the callback) is memoized.

In a normal Parent > Children cycle, every time a prop from Parent changes it will re-render and Children too, even if no props from Children changed.

If we want to avoid Children from rendering when non of its prop changed then we can memoize the component (React.memo). Once we do so, we might have a problem if in Parent we create a function callback on every render, because the memoized Children will interpret as a new function and thus will render again.

To avoid this we can use useCallback in Parent, so when children receives the callback it knows if it is new and should render or not.

Using useCallback when the children is not memoized does not help because Children will render anyway if Parent renders.


Regarding using useRef for the function, I am not totally sure but I would say that it might be similar to using a useCallback with an empty array as dependencies.

like image 177
Alvaro Avatar answered Sep 22 '22 14:09

Alvaro