DEV Community

Caio Felix
Caio Felix

Posted on

React - Entendendo useCallback e useMemo

Motivação

Desde o início no mercado de programação, busquei aprender a fundo o funcionamento das linguagens e ferramentas que utilizo, esse artigo é voltado para auxiliar pessoas que também possuem essa mesma vontade

O mundo mágico do React

Dentre todas libs/frameworks de Javascript para WEB, a minha favorita, sem sombra de dúvidas é o React, porém, o mesmo oferece uma falsa impressão de simplicidade quando se trata do seu funcionamento por baixo dos panos, sendo assim muito mais simples de se aprender que por exemplo o Angular, que oferece um ecossistema inteiro de possibilidades, tornando necessário basicamente o aprendizado de uma nova forma de programar para se utilizar a ferramenta.
Quando se trata do React, temos a possibilidade de criarmos coisas rápidas e performáticas em pouco tempo, sendo possível adequar uma equipe com conhecimento em javascript muito rápido a esse padrão de mercado.
Porém, há momentos que as coisas começam a ficar mais complexas, as aplicações começam a escalar e muitas vezes, a ter problemas de performance.

Problemas da re-renderização

Acho que todo desenvolvedor que já chegou a utilizar o react já obteve o problema da re-renderização excessiva de um componente por conta de um useEffect possuir uma variável/função em seu array de dependência que não para por um segundo de ser executado, porém, não consegue identificar o problema.
O mais simples então é simplesmente remover aquele valor do mesmo, porém, ao fazer isso, o bendito ESLINT já começa a apitar, e se você, como eu, possui ativo a opção do eslint resolver os problemas possíveis ao salvar o arquivo, sabe muito bem a guerra que se iniciara com o mesmo.
Muitas vezes então, somos tentados a utilizar artifícios como desligar a tal bendita regra, para que possamos commitar nossa modificação sem muitos problemas, e conseguirmos finalizar aquela issue que o chefe esta no nosso pescoço para entregarmos.
Só que, como programadores, aquela pulga atrás da orelha fica nos incomodando, já que, se a regra existe, deveria ser seguida não?

Hooks are our saviors

E então é aonde esse artigo realmente irá começar a fazer sentido, pois existem 2 hooks maravilhosos, porém que poucos utilizam que server exatamente para resolver esse problema. Muitas vezes os confundem, pois parecem ter a mesma finalidade, porém existem algumas diferenças bastante significativas, vamos primeiramente explica-las.

useMemo e sua habilidade de salvar nossa performance

Esse subtitulo tem um cunho bem literal da palavra, mesmo parecendo algo um tanto quanto exagerado, o useMemo nos auxilia a memorizar o valor de algo, podendo ser de uma variável ou até um retorno de uma ou mais funções.
Porém por que utiliza-lo? Embelezar o código? Vamos pensar como o react funciona, sempre que um estado do seu componente é alterado, o mesmo é renderizado novamente certo? Quando se trata dessa ação, o componente inteiro é reescrito na memória, sendo assim, seus métodos, funções e variáveis também são.
Tendo isso em vista, imagine que, você possui uma variável que recebe o retorno de uma função complexa, por exemplo, que faz diversos cálculos para determinar o valor de desconto de um produto baseado em parâmetros determinados no perfil do usuário.
Nessa aplicação, aonde essa função foi escrita, temos um input aonde é possível digitar o feedback sobre aquele valor, falando se o mesmo foi acima do esperado, ou abaixo. O que for digitado nesse input, sera salvo em uma variável disposta no estado do componente e com isso temos uma função que visa definir qual o valor para essa variável no estado, utilização básica do hook useState.
Com isso, sempre que o usuário digitar algo nesse input, a conta referente ao valor com desconto será executada, imagina então, o usuário digitando um texto de 1000 letras, reclamando que realmente não gostou do valor e que esperava algo melhor, temos então, uma re-renderização do componente sendo executada 1000 vezes, e com isso, a conta também sendo executada 1000 vezes. Imagina o quanto isso pode custar para performance da sua aplicação?
E para isso, o useMemo é utilizado, o mesmo oferece a possibilidade de adicionar um array de dependências, da mesma forma que o useEffect, para o react saber em quais momentos é necessário que aquele valor seja recriado, sendo assim, começamos a ter um controle da execução daquele valor.

useCallback, evitando o out of memory de cada dia

Enquanto temos o useMemo, memorizando um valor/retorno de uma função, temos também o nosso belissimo useCallback, que ao invés de armazenar um valor, armazena uma função, evitando que a mesma seja reescrita pelo react nas renderizações de estado.
Assim como o useMemo, fica aquela duvida, mas por que isso é realmente necessário, já que a função só ira ser reescrita, não sera reexecutada, como no useMemo. E está exatamente ai o real problema. Sempre que um estado é alterado, o componente é re-renderizado, sempre que isso acontece, as variáveis e funções são reescritas, sendo assim, causando aquele loop que comentei no início do artigo, quando uma função que encapsula um gerenciamento de estado do componente pai é enviada a um componente filho.
Para evitarmos isso basta utilizar o useCallback, garantindo então que a aplicação deixe de reescrever tal função em memória, atendendo então as práticas recomendadas do framework e garantindo a melhor performance para sua aplicação.

Top comments (0)