Impedir adequadamente a re-renderização useEffect em React.js
história de fundo
Eu estava desenvolvendo um aplicativo usando o Firebase no React e fiquei surpreso ao descobrir que havia atingido meu limite de 50 mil leituras naquele dia. Eu não conseguia descobrir como diabos isso era possível, já que meu aplicativo só roda localmente na minha máquina e eu era o ÚNICO usuário.
O problema que enfrentei estava relacionado à remontagem do meu componente ao fazer uma chamada assíncrona que alterava a variável de estado.
Aqui está um exemplo de uma maneira ruim de executar uma chamada assíncrona usando useEffect.
import {useEffect} from 'react'
function Example() {
const [vehicles, setVehicles] = useState([])
const vehiclesRef = collection(db, 'vehicles')
useEffect(() => {
const getVehicles = async () => {
const data = await getDocs(vehiclesRef)
setVehicles(data.docs.map( doc => ( // memory leaks
{
...doc.data(),
id:doc.id
}
)
)
)
}
getVehicles()
},[vehicles])
}
Aviso: não é possível executar uma atualização de estado do React em um componente desmontado. Este é um no-op, mas indica um vazamento de memória em seu aplicativo. Para corrigir, cancele todas as assinaturas e tarefas assíncronas em uma função de limpeza useEffect.
Ao chamar setState, seu componente renderizará novamente para atualizar o DOM com as alterações nesse valor. Isso significa que setVehicles()continuará a inicializar toda vez que o componente for montado. Isso causará um loop infinito de re-renderização, o que custará muito dinheiro ao fazer chamadas de função caras.
Aqui está como eu consertei.
import {useEffect, useRef} from 'react'
function Example() {
const [vehicles, setVehicles] = useState([])
const vehiclesRef = collection(db, 'vehicles')
useEffect(() => {
let isMounted = true
const getVehicles = async () => {
const data = await getDocs(vehiclesRef)
if(isMounted){
setVehicles(data.docs.map( doc => (
{
...doc.data(),
id:doc.id
}
)
)
)
}
}
getVehicles()
console.log(vehicles)
return () => { isMounted = false }
}, [vehicles])
}
Quando isMounted for false, o código não será executado até que esse valor seja definido como true, quando o componente for montado novamente.
Espero que isto ajude!
Codificação de nível
Obrigado por fazer parte da nossa comunidade! Antes de você ir:
- Bata palmas para a história e siga o autor
- Veja mais conteúdo na publicação Level Up Coding
- Siga-nos: Twitter | Linkedin | Boletim de Notícias





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)