1
resposta

[Dúvida] A Lista de Produtos renderiza todos os produtos sempre que um é alterado

Todos os produtos são renderizados sempre que um Produto da Lista é alterado. Mesmo com o export default memo(Produto);.

Entendo que isso aconteça por estarmos usando o contexto de Carrinho: const { carrinho, adicionarProduto, removerProduto } = useCarrinhoContext();.

Toda vez que o Carrinho é atualizado ele renderiza o Produto, mesmo que esse não tenha sofrido mudança em seus valores.

Também tem a constante produtoNoCarrinho que é redefinida em todo render.

Qual seria a melhor solução, nesse cenário com contextos, para que a lista inteira de produtos não seja renderizada sempre que um dos produtos sofrer alteração na quantidade?

1 resposta

Uma solução para evitar a renderização desnecessária dos produtos é utilizar a função useMemo do React para memorizar o resultado da renderização de cada produto e evitar que a renderização seja executada novamente sempre que o carrinho for atualizado. A função useMemo é uma função de ganho de desempenho (performance optimization) do React que memoriza o resultado de uma computação, evitando que essa computação seja re-executada desnecessariamente. Isso é especialmente útil quando uma operação é cara computacionalmente ou envolve uma grande quantidade de dados. Para implementar essa solução, você pode envolver o componente Produto em um useMemo que depende da quantidade de cada produto no carrinho. Dessa forma, o componente Produto só será re-renderizado quando a quantidade do produto for alterada.

Exemplo:

Com essa solução, apenas o produto cuja quantidade foi alterada será renderizado novamente, enquanto os demais produtos serão mantidos em cache pelo useMemo, evitando que a lista inteira de produtos seja renderizada desnecessariamente.

import React, { useMemo } from "react"; import { useCarrinhoContext } from "./CarrinhoContext"; import Produto from "./Produto"; function ListaProdutos() { const { carrinho, adicionarProduto, removerProduto } = useCarrinhoContext(); const produtos = [ { id: 1, nome: "Produto 1", preco: 10 }, { id: 2, nome: "Produto 2", preco: 20 }, { id: 3, nome: "Produto 3", preco: 30 }, ]; return (

{produtos.map((produto) => { const produtoNoCarrinho = carrinho.find((item) => item.id === produto.id); const quantidade = produtoNoCarrinho ? produtoNoCarrinho.quantidade : 0; return useMemo(() => ( <Produto key={produto.id} produto={produto} quantidade={quantidade} onAdicionar={() => adicionarProduto(produto)} onRemover={() => removerProduto(produto)} /> ), [quantidade]); // depende apenas da quantidade do produto no carrinho })}
); } export default ListaProdutos;