Desempenho no React: Passagem por valor e referência e o poder do useMemo
Published: 2024-03-08 01:32:33

As pessoas usam useMemo no React por alguns motivos específicos relacionados à otimização de desempenho e à gestão eficiente de recursos:

**Otimização de Cálculos Intensivos:**

Quando um componente realiza cálculos computacionais ou operações intensivas, usar useMemo pode ajudar a evitar a recálculo desnecessário.
Memoizando o resultado, o React reutiliza a computação anterior, economizando tempo e recursos durante as renderizações subsequentes.
Isso é particularmente útil em situações onde os cálculos são custosos e não precisam ser refeitos a cada renderização.

**Evitar Renderizações Desnecessárias:**

O useMemo é eficaz para evitar a renderização desnecessária de componentes filhos. Se o resultado do useMemo não mudar entre as renderizações, o componente associado não será re-renderizado.

Isso é valioso em casos onde a renderização não é requerida, economizando tempo e melhorando o desempenho geral da aplicação. 

Em componentes que re-renderizam frequentemente, o uso criterioso do useMemo pode contribuir para melhorias perceptíveis de desempenho, reduzindo a carga computacional associada a cálculos repetitivos.

**Preservação de Referências:**

Em situações em que é importante preservar referências específicas na memória, como em temas dinâmicos ou em manipulação direta de objetos complexos, o useMemo é útil.
Ao memoizar objetos, arrays ou funções, você evita a recriação dessas estruturas em cada renderização, garantindo consistência nas referências, o que pode ser crucial em certos contextos.

**Redução do Consumo de Recursos:**

Memoizando valores que não mudam frequentemente, você evita alocações desnecessárias de recursos, como memória, contribuindo para um uso mais eficiente dos recursos disponíveis na aplicação.

Mas é importante exercer cuidado ao usar useMemo, pois seu uso indiscriminado pode levar a uma complexidade desnecessária no código e, em alguns casos, até mesmo impactar negativamente o desempenho, especialmente se não houver um ganho real na economia de cálculos. Deve-se sempre considerar a relação custo-benefício ao decidir onde aplicar o useMemo em um componente React.

E por que ele causaria isso ? Daí entra em outro ponto importante:

**Passagem por Valor:**

Na passagem por valor, uma cópia do valor da variável é passada para a função ou componente. As alterações feitas dentro da função ou componente não afetam diretamente o valor original.
Tipos primitivos, como números, strings e booleanos, são geralmente passados por valor.

```
// Exemplo de passagem por valor
function dobrarNumero(numero) {
  numero = numero * 2;
  console.log("Dentro da função:", numero);
}

let meuNumero = 5;
dobrarNumero(meuNumero);

console.log("Fora da função:", meuNumero);
// Saída: Dentro da função: 10
//        Fora da função: 5
```

**Passagem por Referência:**

Na passagem por referência, o endereço de memória da variável é passado para a função ou componente. Isso significa que qualquer modificação feita dentro da função ou componente afeta diretamente o valor original.
Objetos e arrays em muitas linguagens de programação, incluindo JavaScript, são passados por referência.

```
// Exemplo de passagem por referência
function adicionarElemento(array, elemento) {
  array.push(elemento);
  console.log("Dentro da função:", array);
}

let minhaLista = [1, 2, 3];
adicionarElemento(minhaLista, 4);

console.log("Fora da função:", minhaLista);
// Saída: Dentro da função: [1, 2, 3, 4]
//        Fora da função: [1, 2, 3, 4]
```

A relação com useMemo no React está relacionada ao conceito de "referential equality" (igualdade referencial). Quando o React decide se deve re-renderizar um componente, ele compara as referências dos objetos, não os valores internos. Se as referências forem diferentes, o React assume que algo mudou e desencadeia uma re-renderização.

Ao memoizar um valor com useMemo, você está efetivamente memorizando a referência desse valor. Isso é útil para evitar re-renderizações desnecessárias, pois o React pode verificar se a referência permanece inalterada entre as renderizações. Se a referência permanecer a mesma, o React assume que o valor interno não mudou e evita re-renderizações.


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

const MeuComponente = ({ dados }) => {
  const resultadoCalculado = useMemo(() => {
    // Algum cálculo baseado nos dados
    return dados.reduce((acc, val) => acc + val, 0);
  }, [dados]); // Memoiza com base nas referências dos dados

  return <div>{resultadoCalculado}</div>;
};
```

Neste exemplo, useMemo é usado para memoizar o resultado do cálculo com base na referência do array dados. Se dados não mudar entre as renderizações, o React evita re-executar o cálculo e re-renderizar o componente, proporcionando uma otimização de desempenho.

Esse foi o resumo de hoje e espero ter ajudado alguém <3


Referência: https://www.youtube.com/watch?v=-hBJz2PPIVE