React Hooks (useCallback and useMemo)

Comrades.. There is a problem, I can not understand the chips of the useCallback and useMemo hooks. I have already read the doc and a couple of different articles, but there is no clear picture of what this is necessary for, what is the use of it, in what phase it happens. I would be grateful for any clear explanation.

Author: Torin_21, 2020-10-20

2 answers

Let's start with useCallback

Let's write the simplest counter function.

function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="App">
      <p>counter: {count}</p>
      <button 
      onClick={_ => setCount(prevCount => prevCount + 1)}>
        increment</button>
    </div>
  );
}

Let's add a function there that outputs the text

function App() {
  const [count, setCount] = useState(0);

  const helloConsole = _ => {
    console.log("hi chaps :)");
  };
  helloConsole();

  return (
    <div className="App">
      <p>counter: {count}</p>
      <button 
      onClick={_ => setCount(prevCount => prevCount + 1)}>
        increment</button>
    </div>
  );
}

Now, every time the counter is increased, this function helloConsole will be re-created. That is,

First render

function App() {
  const count = 0; 

  const helloConsole = _ => {
    console.log("hi chaps :)");
  };
  helloConsole();
  //...

Second render

function App() {
  const count = 1; 

  const helloConsole = _ => {
    console.log("hi chaps :)");
  };
  helloConsole();
  //...

Third render

function App() {
  const count = 2; 

  const helloConsole = _ => {
    console.log("hi chaps :)");
  };
  helloConsole();
  //...

And the function helloConsole from the first render is NOT equal to the function from the second render, etc. A new function is created for each render helloConsole with a new link.

// 1 count -------  2 count  //         
helloConsole !== helloConsole

And then you need to think about what will happen if you have a function on a real project that is recreated every time and makes certain calculations inside 500 lines of code. I think the performance of this component will drop.And even depending on the situation and the code, you can see it with the naked eye.

Solution useCallback

Wrap your function in useCallback and add an array dependencies.

  const anyFunc = useCallback(() => {
    // 500 строк кода
  }, [dependencies]);

IMPORTANT NOTES

1.Don't use useCallback without an array of dependencies.

  const anyFunc = useCallback(() => {
    // любой код
  }, []);

You don'T have to write like that. Here you will lose more than you will get. If there is no dependency array, just write a function outside of the component. Something like that.

  const anyFunc = () => {
    // любой код
  };

function App () { // наш компонент

This code is identical to useCallback without the dependency array. I advise you to use the second approach if the array useCallback is empty.

2.Don't use useCallback everywhere you can use.

  const handleClick = useCallback(() => {
    // обработать события клика 
  }, []);

Again, in this code, you will lose more than you will get. Your component will become slower.

Here here you can see how the component works with and without useCallback

Hook useMemo

Unlike useCallback which only memoizes callbacks useMemo memoizes everything.

const List = React.useMemo(() =>
  listOfItems.map(item => ({
    ...item,
    itemProp1: expensiveFunction(props.first),
    itemProp2: anotherPriceyFunction(props.second)
  })), [listOfItems]
)

Example taken from here

In this case, useMemo returns an array.

In the link at the top that I specified written

If you implement useMemo too often in an application, it can harm the performance.

If you will use useMemo frequently  this can harm the performance of the application.

This means that the second remark that I wrote at the top for useCallback is also relevant for useMemo.

Also if you try to memoize the callback in useMemo it will be identical to using useCallback

useCallback(fn, deps) — это эквивалент useMemo(() => fn, deps).
 3
Author: Избыток Сусликов, 2020-11-25 19:16:47

useCallback remembers the function and does not recreate it for optimization purposes.

useMemo remembers the value and does not recalculate it (complex mathematical calculations), also for optimization.

It is used depending on what you need: a function or a value.

 1
Author: Konstantin Modin, 2020-10-23 14:22:42