React hook, useEffect o cómo domesticar los rerenders
Con el hook de React useEffect
podemos especificar cuándo queremos que un código determinado se ejecute, en lugar de ejecutarse a cada renderizado de nuestro componente
Para qué es útil el useEffect
Los hooks de React
son herramientas muy potentes que nos sirven sobre todo para extraer código y poder reutilizarlo de manera muy simple y agradable
Pero con el useEffect
esta definición se queda corta
El useEffect
es la manera que tenemos en React
de controlar y decidir cuándo queremos que se ejecute un código concreto
Mejor lo vemos con un ejemplo
Vamos a introducir un console.log()
en un componente que también tendrá un botón, y cada vez que lo apretemos actualizaremos un contador y esto obligará a React
a renderizar el componente otra vez
Y cuando el componente se vuelva a renderizar, el console.log
se volverá a ejecutar
import React, { useState } from 'react'
const Button = () => {
console.log('me estoy repintando')
const [counter, setCounter] = useState(0)
return (
<div>
<button onClick={() => setCounter(prev => prev + 1)}>contador: {counter}</button>
</div>
)
}
export default Button
Cada vez que actualizamos el contador el componente Button
se vuelve a renderizar y con ello vuelve a ejecutar el console.log
Esto nos puede ser útil, pero qué pasa cuando se trata de un código que sólo queremos que se ejecute una vez?
El código más típico que queremos que se utilice sólo una vez es cuando pedimos información de un servidor externo
En ese caso, para evitar que ese código se vaya repitiendo a cada repintado, necesitamos utilizar el useEffect
import React, { useState, useEffect } from 'react'
const Button = () => {
useEffect(() => {
console.log('pidiendo información a una API externa')
}, [])
const [counter, setCounter] = useState(0)
return (
<div>
<button onClick={() => setCounter(prev => prev + 1)}>contador: {counter}</button>
</div>
)
}
export default Button
Y aquí puedes ver como el console.log
sólo se ejecuta una única vez, y aunque el componente se renderize mil veces sólo veremos una orden en la consola
Cómo funciona el useEffect
?
La función se especifica así
useEffect(() => {
console.log('código a ejecutar una sola vez')
}, [])
Por lo tanto, tiene dos argumentos
useEffect(arg1, arg2)
El primer argumento es una función, y el código de dentro será lo que ejecutemos cuando toque
useEffect(() => {}, arg2)
El segundo argumento define cuándo se ejecutará ese código, y es un array
de dependencias, esto es, todo lo que vaya dentro de ese array, cuando cambie, se volverá a ejecutar el código del useEffect
useEffect(() => {}, [])
Cuando ese array de dependencias está vacío, ese código sólo se ejecutará una vez al principio
Cuando el array tiene alguna variable, ese código sólo se ejecutará cuando esa variable cambie
import React, { useState, useEffect } from 'react'
const Button = () => {
const mivariable = 'siempre tendré el mismo valor'
useEffect(() => {
console.log('código especial')
}, [mivariable])
const [counter, setCounter] = useState(0)
return (
<div>
<button onClick={() => setCounter(prev => prev + 1)}>contador: {counter}</button>
</div>
)
}
export default Button
En este código el console
que hay dentro del useEffect sólo se ejecuta una vez al principio, y nunca más, ya que la variable mivariable
nunca cambia
Ahora vamos a hacer que sí que cambie
import React, { useState, useEffect } from 'react'
const Button = () => {
console.log('me estoy repintando')
const [mivariable, setMivariable] = useState(0)
useEffect(() => {
console.log('código especial')
}, [mivariable])
const [counter, setCounter] = useState(0)
return (
<div>
<button onClick={() => setCounter(prev => prev + 1)}>contador: {counter}</button>
<button onClick={() => setMivariable(prev => prev + 1)}>cambiar el contenido de mivariable</button>
</div>
)
}
export default Button
Ahora cada vez que el valor de mivariable
cambia, el código de dentro del useEffect
se ejecuta
Por lo tanto, el useEffect
es la manera React
que tenemos para controlar cuándo se ejecuta un código determinado
Y esto lo puedes ver con el console.log('me estoy repintando')
, este console.log se ejecuta siempre que hay un repintado, lo que ocurre al apretar cualquiera de los dos botones
Listos! 🙋♂️
Lista de correo: escribo algo de tanto en cuanto