Ganchos de useEffect
reacción
El useEffect
gancho le permite realizar efectos secundarios en sus componentes.
Algunos ejemplos de efectos secundarios son: obtención de datos, actualización directa del DOM y temporizadores.
useEffect
acepta dos argumentos. El segundo argumento es opcional.
useEffect(<function>, <dependency>)
Usemos un temporizador como ejemplo.
Ejemplo:
Úselo setTimeout()
para contar 1 segundo después del renderizado 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'));
¡¡Pero espera!! ¡Sigo contando aunque solo debería contar una vez!
useEffect
se ejecuta en cada render. Eso significa que cuando cambia el conteo, ocurre un renderizado, que luego desencadena otro efecto.
Esto no es lo que queremos. Hay varias formas de controlar cuándo se presentan los efectos secundarios.
Siempre debemos incluir el segundo parámetro que acepta una matriz. Opcionalmente, podemos pasar dependencias a useEffect
esta matriz.
1. No pasó ninguna dependencia:
useEffect(() => {
//Runs on every render
});
2. Una matriz vacía:
useEffect(() => {
//Runs only on the first render
}, []);
3. Props o valores de estado:
useEffect(() => {
//Runs on the first render
//And any time any dependency value changes
}, [prop, state]);
Entonces, para solucionar este problema, solo ejecutemos este efecto en el renderizado inicial.
Ejemplo:
Solo ejecute el efecto en el renderizado 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'));
Ejemplo:
Aquí hay un ejemplo de un useEffect
Hook que depende de una variable. Si la count
variable se actualiza, el efecto se ejecutará nuevamente:
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'));
Si hay varias dependencias, deben incluirse en la useEffect
matriz de dependencias.
¡Obtener la certificación!
$95 INSCRÍBETE
Limpieza de efectos
Algunos efectos requieren limpieza para reducir las fugas de memoria.
Se deben desechar los tiempos de espera, las suscripciones, los detectores de eventos y otros efectos que ya no se necesitan.
Hacemos esto incluyendo una función de retorno al final del useEffect
Hook.
Ejemplo:
Limpie el temporizador al final del 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 borrar el temporizador, tuvimos que nombrarlo.