useEffect no es para todo: 5 cosas que hacía mal y cómo las arreglé
basado en 'You Might Not Need an Effect' de la doc de React, pero con ejemplos reales de mi camello
Contents
Parce, hace un año revisé un proyecto mío viejo y conté 43 useEffect. Hoy tiene 9. Y funciona mejor. Les cuento los 5 errores que más cometía, por si se ven reflejados.
1. Estado derivado en un efecto
// mal
const [nombreCompleto, setNombreCompleto] = useState('')
useEffect(() => {
setNombreCompleto(nombre + ' ' + apellido)
}, [nombre, apellido])
// bien
const nombreCompleto = nombre + ' ' + apellido
Si algo se puede calcular con lo que ya tienes, calcúlalo durante el render. El efecto hace que el componente se pinte dos veces: una con el valor viejo y otra con el nuevo.
2. Filtrar una lista en un efecto
// bien
const visibles = todos.filter(t => t.hecho === mostrarHechos)
// y si la lista es enorme y el filtro es caro:
const visibles = useMemo(
() => todos.filter(t => t.hecho === mostrarHechos),
[todos, mostrarHechos]
)
Ojo: useMemo solo cuando lo mediste y de verdad es caro. No lo pongan en todo "por si acaso".
3. La lógica de un evento metida en un efecto
// mal: mandar el POST cuando cambia un estado
useEffect(() => {
if (enviado) {
fetch('/api/pedido', { method: 'POST', body: JSON.stringify(pedido) })
}
}, [enviado])
// bien: mandarlo donde pasa la acción
function handleSubmit() {
fetch('/api/pedido', { method: 'POST', body: JSON.stringify(pedido) })
}
La pregunta clave: ¿esto pasa porque el componente se mostró, o porque el usuario hizo algo? Si es lo segundo, va en el handler.
4. Resetear estado cuando cambia una prop
// mal
useEffect(() => {
setComentario('')
}, [userId])
// bien: que React lo trate como otro componente
<Perfil key={userId} userId={userId} />
Con una key distinta, React desmonta y vuelve a montar. Todo el estado interno arranca limpio. Es el truco más subestimado de React, pues.
5. Fetch sin limpieza (race conditions)
Este es el que más bugs me dio. El usuario cambia rápido de perfil, la respuesta vieja llega después de la nueva y te muestra el nombre equivocado.
useEffect(() => {
let ignorar = false
fetch('/api/usuarios/' + id)
.then(res => res.json())
.then(data => {
if (!ignorar) setUsuario(data)
})
return () => {
ignorar = true
}
}, [id])
También se puede con AbortController. Y para una app de verdad, usen TanStack Query o SWR, que ya resuelven caché, reintentos y todo esto.
Bonus: "¡mi efecto corre dos veces!"
En desarrollo, con StrictMode, React monta, desmonta y vuelve a montar a propósito, para que encuentres efectos sin limpieza. En producción corre una vez. No quiten el StrictMode.
La fuente de casi todo esto es la doc oficial, que está buenísima y en inglés sencillo: You Might Not Need an Effect. Léanla completa, vale la pena.
Written by
Camilo Restrepo
Fullstack dev en Medellín 🇨🇴 React, Node, Postgres. Trabajo remoto pa' empresas gringas. Parce, si necesitás algo, me escribís.
Get the best of #codigo_en_espanol weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment