Ganchos de useEffect
reação
O useEffect
Gancho permite que você execute efeitos colaterais em seus componentes.
Alguns exemplos de efeitos colaterais são: buscar dados, atualizar diretamente o DOM e cronômetros.
useEffect
aceita dois argumentos. O segundo argumento é opcional.
useEffect(<function>, <dependency>)
Vamos usar um temporizador como exemplo.
Exemplo:
Use setTimeout()
para contar 1 segundo após a renderização inicial:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
});
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById('root'));
Mas espere!! Eu continuo contando mesmo que devesse contar apenas uma vez!
useEffect
é executado em cada renderização. Isso significa que quando a contagem muda, uma renderização acontece, o que aciona outro efeito.
Não é isso que queremos. Existem várias maneiras de controlar quando os efeitos colaterais são executados.
Devemos sempre incluir o segundo parâmetro que aceita um array. Opcionalmente, podemos passar dependências para useEffect
esse array.
1. Nenhuma dependência passada:
useEffect(() => {
//Runs on every render
});
2. Uma matriz vazia:
useEffect(() => {
//Runs only on the first render
}, []);
3. Adereços ou valores de estado:
useEffect(() => {
//Runs on the first render
//And any time any dependency value changes
}, [prop, state]);
Então, para corrigir esse problema, vamos executar esse efeito apenas na renderização inicial.
Exemplo:
Execute o efeito apenas na renderização inicial:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, []); // <- add empty brackets here
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById('root'));
Exemplo:
Aqui está um exemplo de um useEffect
Hook que é dependente de uma variável. Se a count
variável for atualizada, o efeito será executado novamente:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Counter() {
const [count, setCount] = useState(0);
const [calculation, setCalculation] = useState(0);
useEffect(() => {
setCalculation(() => count * 2);
}, [count]); // <- add the count variable here
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
<p>Calculation: {calculation}</p>
</>
);
}
ReactDOM.render(<Counter />, document.getElementById('root'));
Se houver várias dependências, elas devem ser incluídas na useEffect
matriz de dependências.
Obter certificação!
$ 95 INSCRIÇÃO
Limpeza do efeito
Alguns efeitos requerem limpeza para reduzir vazamentos de memória.
Tempos limite, assinaturas, ouvintes de eventos e outros efeitos que não são mais necessários devem ser descartados.
Fazemos isso incluindo uma função de retorno no final do useEffect
Hook.
Exemplo:
Limpe o cronômetro no final do useEffect
Gancho:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
let timer = setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
return () => clearTimeout(timer)
}, []);
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById("root"));
Nota: Para limpar o cronômetro, tivemos que nomeá-lo.