E aí, programador! o/
Nessa aula você irá conhecer o segundo hook mais usado do React, depois do useState(), o useEffect(). O useEffect serve para sincronizar a aplicação com sistemas externos através de efeitos colaterais, ou seja, ele cria funções que são executadas quando uma dependência é modificada (como um efeito colateral dessa mudança).
Mas atenção! Muitas pessoas usam o useEffect para executar uma função após uma mudança no state, mesmo quando é a própria aplicação que causa essa mudança (ex.: em eventos). Isso pode gerar usos desnecessários do useEffect. Faça o possível para utilizá-lo somente em sincronização com sistemas externos (ex.: APIs, websocket, integrações, etc).
Nessa primeira aula iremos mostrar o useEffect() com um exemplo básico, na próxima traremos um uso mais realista.
Crie um novo projeto com o Vite e remova o conteúdo inicial desnecessário.
No componente App.jsx adicione o seguinte conteúdo:
Obs.: repare que o useEffect é composto de dois argumentos, o callback e o array de dependencias.
Obs².: é muito importante passar o array de dependências, pois sem ele o useEffect será executado em todas as renderizações do componente.
import { useEffect, useState } from "react"
function App() {
let [counter, setCounter] = useState(0)
useEffect(() => {
alert("O efeito colateral foi ativado!")
}, [counter])
return (
<>
<h1>Conhecendo o useEffect()</h1>
<button
onClick={() => setCounter(count => count + 1)}
>
Contador: {counter}
</button>
</>
)
}
export default App
É muito importante passar o array de dependências, pois sem ele o useEffect será executado em todas as renderizações do componente. Crie um segundo estado e remove o array de dependências, você verá que o alert é exibido em cada renderização:
import { useEffect, useState } from "react"
function App() {
let [counter, setCounter] = useState(0)
let [counter2, setCounter2] = useState(0)
useEffect(() => {
alert("O efeito colateral foi ativado!")
})
return (
<>
<h1>Conhecendo o useEffect()</h1>
<button
onClick={() => setCounter(count => count + 1)}
>
Contador: {counter}
</button>
<button
onClick={() => setCounter2(count => count + 1)}
>
Contador 2: {counter2}
</button>
</>
)
}
export default App
Por fim, o useEffect() conta com outro recurso importante, um mecanismo de limpeza. Isso existe para removermos manualmente recursos associados ao componente quando o componente for desmontado, evitando vazamento de memória e outros problemas. Para isso, retornamos uma função dentro do useEffect(), ela será executada sempre que o componente for desmontado, fazendo a limpeza necessária.
Obs.: o componente separado Counter só foi criado para demonstrar a desmontagem através da renderização condicional.
import { useEffect, useState } from "react"
function Counter() {
let [counter, setCounter] = useState(0)
useEffect(() => {
console.log("O efeito colateral foi ativado!")
return () => {
console.log("Componente desmontado! Fazendo a limpeza...")
}
})
return (
<button onClick={() => setCounter(count => count + 1)}>
Contador: {counter}
</button>
)
}
function App() {
const [show, setShow] = useState(false)
return (
<>
<h1>Conhecendo o useEffect()</h1>
<div>
<input type="checkbox" id="show" value={show} onChange={() => setShow(state => !state)} />
<label htmlFor="show">Exibir Contador</label>
</div>
{show ?
<Counter />
: null
}
</>
)
}
export default App