⊗jsrtPmHkUCb 16 of 47 menu

O Hook de Otimização de Desempenho useCallback no React

Nesta lição, veremos o seguinte hook para otimização de desempenho: useCallback.

O hook useCallback é semelhante à API useMemo, a diferença é que o primeiro armazena em cache um valor entre as renderizações de tela, e o segundo - uma função de retorno de chamada (callback). Isso nos permite não reiniciar funções que consomem muitos recursos quando não é necessário e pode ser usado ao passar uma função para componentes filhos.

Vamos entender melhor com um exemplo. Primeiro, vamos criar um componente App e definir um estado num nele:

const [num, setNum] = useState(0);

Vamos ter um botão, ao clicar no qual num é incrementado em 1, e um parágrafo onde exibiremos o valor de num:

return ( <div> <button onClick={() => setNum(num + 1)}>clique</button> <p>cliques: {num}</p> </div> );

Agora, suponha que temos em App outra lista de itens que será complementada ao clicar em outro botão. Para armazenar os elementos desta lista, vamos criar um estado items:

const [items, setItems] = useState([]);

E então escreveremos uma função addItem para adicioná-los:

function addItem() { setItems([...items, 'novo item']); }

Agora vamos escrever o código para exibir os elementos da lista e movê-lo para um componente filho Items, que receberá o array de elementos e a função para adicioná-los como props. Vamos lembrar de adicionar um log no console para vermos quando nosso Items será renderizado novamente:

function Items({ items, addItem }) { const result = items.map((item, index) => { return <p key={index}>{item}</p>; }); console.log('Items render'); return ( <div> <h3>Nossos itens</h3> {result} <button onClick={addItem}>adicionar item</button> </div> ); } export default Items;

Vamos colocar Items no final do componente App e passar para ele o array items e a função para adicionar elementos addItem:

return ( <> <div> <button onClick={() => setNum(num + 1)}>clique</button> <p>cliques: {num}</p> <br /> </div> <Items items={items} addItem={addItem} /> </> );

Agora vamos clicar nos botões e verificar que num aumenta e novos elementos são adicionados à lista. Ao abrir o console, veremos que nossa lista é renderizada novamente a cada vez, mesmo se clicarmos no botão que aumenta num.

Se temos uma lista pequena, está tudo bem, mas e se for esperado que ela seja grande e tenha muitos outros elementos? Sem problemas - você dirá, pois na lição anterior vimos a API memo, exatamente para evitar renderizações desnecessárias de componentes.

Então, vamos envolver nosso componente Items em memo e pronto. A propósito, isso pode ser feito diretamente na exportação de Items:

export default memo(Items);

Não vamos esquecer de importar memo:

import { memo } from 'react';

Agora vamos abrir o console e clicar nos botões. Todos os esforços em vão! Nós memorizamos o componente, mas ao clicar no botão 'clique' o componente Items ainda assim é renderizado novamente a cada vez.

O problema é que quando o componente pai é renderizado novamente, suas funções são recriadas - isso se aplica à nossa função addItem, que passamos para Items.

É exatamente nesse momento que o hook useCallback nos ajudará. Vamos aplicá-lo. Primeiro, vamos importá-lo para App:

import { useCallback } from 'react';

Em seguida, vamos transformar a simples declaração de função addItem em uma Expressão de Função (Function Expression), especificar como primeiro parâmetro para useCallback nossa função na forma de um callback. Como segundo parâmetro, entre colchetes, especificaremos as dependências - todas as variáveis reativas participantes da função, no nosso caso é o array items:

const addItem = useCallback(() => { setItems(() => [...items, 'Novo item']); }, [items]);

Pronto! Dessa forma, armazenamos em cache a função. Clicamos novamente nos botões e vemos que agora, ao clicar no botão 'clique', nosso componente filho não é mais renderizado novamente.

Crie um componente App, coloque nele um parágrafo com texto. Crie um estado com o valor inicial 'texto' e exiba-o no parágrafo. Faça com que ao clicar no parágrafo, um ponto de exclamação seja adicionado ao final do texto.

Crie um componente filho Products, no qual você terá um botão para adicionar um novo produto. Coloque-o em App. No componente pai, crie um estado com um array de produtos e uma função de adição de um novo produto. Passe-os como props para o componente filho, exiba nele o array passado como uma lista ul.

Em Products, exiba no console o texto 'products render'. Envolva Products em memo. Clique no parágrafo e no botão. Verifique que ao clicar no parágrafo, o componente filho ainda é renderizado novamente.

Armazene em cache a função para adicionar produtos, envolvendo-a no hook useCallback. Clique no parágrafo e no botão. Verifique que ao clicar no parágrafo, o componente filho não é mais renderizado novamente.

Português
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Nós usamos cookies para o funcionamento do site, análises e personalização. O processamento de dados é realizado de acordo com a Política de Privacidade.
aceitar todas configurar rejeitar