DEV Community

Gabriel Teixeira da Silva
Gabriel Teixeira da Silva

Posted on

Compreendendo as Diferenças entre useEffect, useMemo e useCallback

Mas, o que é um Hook?

No React, um hook é uma função especial que permite que você "ligue-se" a recursos e funcionalidades do React em componentes funcionais. Os hooks foram introduzidos no React 16.8 para permitir o uso de estados e outros recursos anteriormente disponíveis apenas em componentes de classe em componentes funcionais.
Os hooks permitem que você adicione funcionalidades de gerenciamento de estado, efeitos colaterais, contexto, referências e muito mais aos seus componentes funcionais.
Neste artigo, abordaremos as distinções entre três hooks essenciais do React: useEffect, useMemo e useCallback.

useEffect

O useEffect trata principalmente de lidar com efeitos colaterais em componentes React. Efeitos colaterais geralmente incluem operações como buscar dados, manipular o DOM e gerenciar assinaturas. Aqui está uma análise das suas principais características:

  1. Propósito: O propósito principal do useEffect é executar código que tenha efeitos colaterais. Esses efeitos colaterais podem estar relacionados à renderização do componente ou a mudanças em suas dependências.

  2. Uso: Você fornece uma função de retorno para o useEffect, e o React executa essa função depois que o componente foi renderizado ou quando as dependências especificadas foram alteradas.

  3. Casos de Uso Típicos: O useEffect é comumente utilizado para tarefas como buscar dados, configurar e limpar ouvintes de eventos e realizar ações em resposta a mudanças em props ou estado.

Exemplo de Uso

import React, { useState, useEffect } from 'react';

function ExemploUseEffect() {
  // Defina um estado para armazenar uma contagem
  const [count, setCount] = useState(0);

  // useEffect é usado para realizar efeitos colaterais
  useEffect(() => {
    // Atualize o título da página com a contagem atual
    document.title = `Contagem: ${count}`;

    // Este código será executado após cada renderização
    // e sempre que 'count' for alterado.

    // É uma boa prática retornar uma função de limpeza
    // se você precisar desfazer algum efeito.
    return () => {
      document.title = 'Aplicação React'; // Reverter o título
    };
  }, [count]); // Especifique as dependências aqui

  return (
    <div>
      <p>Contagem: {count}</p>
      <button onClick={() => setCount(count + 1)}>Incrementar</button>
    </div>
  );
}

export default ExemploUseEffect;
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, usamos o useEffect para atualizar o título da página com a contagem atual toda vez que o estado count for alterado. Observamos que passamos [count] como um segundo argumento para o useEffect. Isso especifica as dependências do efeito, ou seja, quando o efeito deve ser executado novamente. Neste caso, o efeito será acionado sempre que count mudar.

Além disso, fornecemos uma função de retorno no useEffect. Esta função será chamada quando o componente for desmontado ou quando a dependência count mudar novamente. É uma prática recomendada para fazer a limpeza de efeitos quando eles não são mais necessários.

Quando você clicar no botão "Incrementar", a contagem aumentará e o título da página será atualizado de acordo com o valor atual da contagem.

useMemo

O useMemo é inteiramente voltado para a memorização. A memorização é uma técnica na qual o resultado de uma função ou expressão custosa é armazenado em cache, de modo que seja recalculado apenas quando suas dependências mudam. Aqui está uma análise das suas principais características:

  1. Propósito: O useMemo é usado para memorizar (armazenar em cache) o resultado de uma função ou expressão. Isso pode melhorar o desempenho ao evitar cálculos desnecessários.

  2. Uso: Você fornece uma função e uma matriz de dependências para o useMemo. O React executa a função e armazena em cache seu resultado. Se as dependências mudarem, a função é reexecutada e o resultado é atualizado.

  3. Casos de Uso Típicos: A memorização é útil para cálculos computacionalmente custosos ou para evitar renderizações desnecessárias de componentes.

Exemplo de Uso

import React, { useState, useMemo } from 'react';

function ExemploUseMemo() {
  // Defina dois estados para armazenar números
  const [num1, setNum1] = useState(5);
  const [num2, setNum2] = useState(10);

  // Use useMemo para calcular a soma dos números apenas quando eles mudarem
  const soma = useMemo(() => {
    console.log('Calculando a soma...');
    return num1 + num2;
  }, [num1, num2]); // Dependências

  return (
    <div>
      <p>Número 1: {num1}</p>
      <p>Número 2: {num2}</p>
      <p>Soma: {soma}</p>
      <button onClick={() => setNum1(num1 + 1)}>Incrementar Número 1</button>
      <button onClick={() => setNum2(num2 + 1)}>Incrementar Número 2</button>
    </div>
  );
}

export default ExemploUseMemo;
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, estamos usando o useMemo para calcular a soma dos números num1 e num2. O cálculo da soma é uma operação simples, mas suponha que tivéssemos uma operação computacionalmente cara em vez disso.

O useMemo recebe uma função de cálculo e uma matriz de dependências como argumentos. A função de cálculo será executada apenas quando uma das dependências (num1 ou num2) mudar. Isso significa que a soma só será recalculada quando um dos números for incrementado.

Dentro da função de cálculo, você pode realizar qualquer operação que desejar. Neste exemplo, usamos um console.log para demonstrar quando a soma está sendo calculada.

Ao clicar nos botões "Incrementar Número 1" ou "Incrementar Número 2", apenas o número relevante é atualizado, e a soma é recalculada somente quando necessário, graças ao uso do useMemo. Isso ajuda a evitar cálculos desnecessários e melhora o desempenho do componente.

useCallback

O useCallback está intimamente relacionado ao useMemo, mas foca na memorização de funções em vez de valores. É particularmente útil ao passar funções de retorno de chamada para componentes filhos. Aqui está uma análise das suas principais características:

  1. Propósito: useCallback é usado para memorizar (armazenar em cache) uma função de modo que ela seja recriada apenas quando suas dependências mudam. Isso pode otimizar o desempenho ao passar funções de retorno de chamada como propriedades.

  2. Uso: Você fornece uma função e uma matriz de dependências para useCallback. O React retorna uma versão memorizada da função. Se as dependências mudarem, uma nova função memorizada é criada.

  3. Casos de Uso Típicos: É comumente usado para memorizar funções de retorno de chamada, especialmente ao passar essas funções para componentes filhos.

Exemplo de Uso

import React, { useState, useCallback } from 'react';

function ExemploUseCallback() {
  // Defina um estado para armazenar um contador
  const [contador, setContador] = useState(0);

  // Defina uma função de retorno de chamada para incrementar o contador
  const incrementarContador = useCallback(() => {
    setContador(contador + 1);
  }, [contador]); // Dependência: contador

  return (
    <div>
      <p>Contador: {contador}</p>
      <button onClick={incrementarContador}>Incrementar Contador</button>
    </div>
  );
}

export default ExemploUseCallback;
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, estamos usando o useCallback para memorizar a função incrementarContador. A função incrementarContador simplesmente incrementa o valor do contador quando o botão é clicado.

Observe que passamos [contador] como uma matriz de dependência para useCallback. Isso significa que a função incrementarContador será memorizada e recriada apenas quando a dependência contador mudar. Isso é útil para evitar que a função seja recriada em cada renderização, economizando recursos.

Ao clicar no botão "Incrementar Contador", o valor do contador aumenta, e a função incrementarContador é chamada sem ser recriada desnecessariamente. Isso melhora a eficiência e é particularmente útil ao passar essa função como propriedade para componentes filhos, onde a memorização pode economizar ciclos de renderização.

Principais Diferenças

  1. useEffect é usado para lidar com efeitos colaterais e executar código após a renderização ou quando certas dependências mudam.

  2. useMemo é usado para memorizar o resultado de uma função ou expressão a fim de evitar recalculos desnecessários.

  3. useCallback é usado para memorizar funções, sendo especialmente útil para otimizar componentes filhos que dependem de funções de retorno de chamada.

Todos os três hooks recebem uma matriz de dependências. Quando essas dependências mudam, useEffect executa sua função de efeito, useMemo recalcula o valor e useCallback recria a função memorizada.

Em resumo, esses hooks têm propósitos distintos e são ferramentas valiosas para gerenciar diferentes aspectos dos seus componentes React. Compreender quando e como usar useEffect, useMemo e useCallback podem contribuir para tornar seus aplicativos React mais eficientes e tornar a
manutenção mais simples.

Referências

Top comments (4)

Collapse
 
artenlf profile image
Luís Felipe Arten

Muito bom!!! Parabéns pelo artigo! Eu tive bastante dificuldade com o useMemo e useCallback. O artigo é ouro para quem tem dificuldades em saber o que e quando aplicar.

Collapse
 
cherryramatis profile image
Cherry Ramatis • Edited

Muito foda o artigo primo! Eu sempre tenho duvida com useEffect e useMemo, mto foda a didatica.

Se me permitir uma dica:

Nos seus blocos de codigo vc pode incluir typescriptreact na frente do "`" assim habilitando syntax highlight

Collapse
 
gabrielteixeira44 profile image
Gabriel Teixeira da Silva

Muito obrigado pela dica, não sabia dessa. Obrigado!!

Collapse
 
demenezes profile image
deMenezes

Descobri o useMemo e useCallback há pouco tempo e estou adorando usar, são otimos

Só queria propor uma correção na parte que diz:

  • useMemo: "A memorização é uma técnica na qual o resultado de uma função ou expressão custosa é armazenado em cache, de modo que seja recalculado apenas quando suas dependências mudam"

E:

  • useCallback: "é usado para memorizar (armazenar em cache) uma função de modo que ela seja recriada apenas quando suas dependências mudam"

Diferente do useEffect, o useMemo e useCallback não são recalculados quando algum valor do array de dependências muda.

O que acontece com esses dois é: a cada render do componente, o React compara a Array de dependência atual com a do último render. Se forem iguais, ele usa o valor armazenado em cache. Se forem diferentes, ele reexecuta o useMemo/useCallback para gerar o novo valor.

A diferença é sutil, mas lendo pela doc desses hooks fica mais claro.