O useMemo é um gancho usado no componente funcional de react que retorna um valor memorizado. Na Ciência da Computação, memoização é um conceito usado em geral quando não precisamos recalcular a função com um determinado argumento na próxima vez que ela retorna o resultado armazenado em cache. Uma função memoized lembra os resultados da saída para um determinado conjunto de entradas. Por exemplo, se houver uma função para adicionar dois números, e dermos o parâmetro como 1 e 2 pela primeira vez, a função adicionará esses dois números e retornará 3, mas se as mesmas entradas vierem novamente, retornaremos o cache valor ou seja, 3 e não computar com a função add novamente. No react também, usamos este conceito, sempre que no componente React, o estado e props não mudam o componente e o componente não é renderizado novamente, ele mostra a mesma saída.

Sintaxe:

const memoizedValue = useMemo(functionThatReturnsValue, 
                                   arrayDepencies)

Exemplo : Quando não usamos o gancho useMemo.

import React, {useState} from 'react';
  
function App() {
  const [number, setNumber] = useState(0)
  const squaredNum =  squareNum(number);
  const [counter, setCounter] = useState(0);
  
 // Change the state to the input
  const onChangeHandler = (e) => {
    setNumber(e.target.value);
  }
    
  // Increases the counter by 1
  const counterHander = () => {
    setCounter(counter + 1);
  }
  return (
    <div className="App">
      <h1>Welcome to Geeksforgeeks</h1>
      <input type="number" placeholder="Enter a number" 
        value={number} onChange={onChangeHandler}>
      </input>
        
      <div>OUTPUT: {squaredNum}</div>
      <button onClick= {counterHander}>Counter ++</button>
      <div>Counter : {counter}</div>
    </div>
  );
}
  
// function to square the value
function squareNum(number){
  console.log("Squaring will be done!");
  return Math.pow(number, 2);
}
  
export default App;

Saída: No exemplo acima, temos um componente App e esse componente está fazendo duas coisas, uma é elevar ao quadrado um número na entrada fornecida e incrementar o contador. Temos dois estados aqui, número e contador, sempre que qualquer um dos estados muda, o componente é renderizado novamente. Por exemplo, se alterarmos o valor de entrada do número, a função squareNum será executada, e se incrementarmos o contador novamente, a função squareNum será executada. Podemos ver isso no console. 

Nesse caso, podemos ver que, mesmo se alterarmos o número de entrada uma vez, mas clicarmos no contador de incremento várias vezes, nossa função squareNum será executada sempre que clicarmos no botão do contador de incremento várias vezes. Isso está acontecendo porque o componente App é renderizado novamente sempre que alteramos o estado do contador.

Agora vamos resolver este problema usando o gancho useMemo.

Exemplo: Quando usamos useMemo Hook

import React, {useState} from 'react';
  
function App() {
  const [number, setNumber] = useState(0)
  // Using useMemo
  const squaredNum = useMemo(()=> {
    return squareNum(number);
  }, [number])
  const [counter, setCounter] = useState(0);
  
 // Change the state to the input
  const onChangeHandler = (e) => {
    setNumber(e.target.value);
  }
    
  // Increases the counter by 1
  const counterHander = () => {
    setCounter(counter + 1);
  }
  return (
    <div className="App">
      <h1>Welcome to Geeksforgeeks</h1>
      <input type="number" placeholder="Enter a number"
          value={number} onChange={onChangeHandler}>
      </input>
        
      <div>OUTPUT: {squaredNum}</div>
      <button onClick= {counterHander}>Counter ++</button>
      <div>Counter : {counter}</div>
    </div>
  );
}
  
// function to square the value
function squareNum(number){
  console.log("Squaring will be done!");
  return Math.pow(number, 2);
}
  
export default App;

Saída: Agora, no exemplo acima, usamos o gancho memo do usuário, aqui a função que retorna o valor, ou seja, squareNum é passada dentro do useMemo e dentro das dependências do array, usamos o número, pois o squareNum será executado apenas quando o número alterar. Se aumentarmos o contador e o número permanecer o mesmo no campo de entrada, o squareNum não será executado novamente. Vamos ver a saída abaixo.

Agora podemos ver no console que o squareNum está rodando apenas quando há uma mudança na caixa de entrada e não quando o botão do contador de incremento é clicado.

Nota: A memorização nunca é gratuita, estamos trocando espaço por tempo.