¿Qué es el Error de Hidratación en Next.js?
El error de hidratación (Hydration Failed o Text content does not match server-rendered HTML) es uno de los problemas más comunes en aplicaciones desarrolladas con Next.js que utilizan renderizado del lado del servidor (SSR). Ocurre cuando el árbol de componentes generado en el servidor difiere del primer renderizado ejecutado en el navegador del cliente.
Causas Principales del Error
Existen diversos motivos por los cuales el servidor y el cliente pueden generar HTML distinto:
- Uso de funciones que devuelven valores dinámicos en tiempo de ejecución como
new Date()oMath.random()directamente en el marcado. - Extensiones del navegador que modifican el DOM antes de que React complete el proceso de hidratación.
- Diferencias en la localización o formato de fechas y números entre el entorno del servidor (Node.js) y el cliente.
- Uso incorrecto de etiquetas HTML (por ejemplo, anidar un bloque
<p>dentro de otro).
Método 1: Usar un estado booleano para renderizado exclusivo en el cliente
Si tu componente depende de APIs del navegador como window, localStorage o fechas dinámicas, puedes asegurarte de que solo se renderice después de que el componente se haya montado.
- Importa
useStateyuseEffectdesde React. - Crea una variable de estado para controlar si el componente está montado.
- Actualiza el estado dentro de un
useEffect. - Retorna un marcador de posición (skeleton o null) si el componente aún no se ha hidratado.
import { useState, useEffect } from 'react';
export default function ComponenteDinamico() {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
if (!isMounted) {
return null; // O un componente de carga
}
return <div>Hora actual: {new Date().toLocaleTimeString()}</div>;
}
Método 2: Desactivar la hidratación en elementos específicos
Si necesitas renderizar contenido que inevitablemente será diferente entre el servidor y el cliente, puedes indicarle a React que ignore la discrepancia de contenido utilizando el atributo suppressHydrationWarning.
- Localiza la etiqueta HTML exacta que genera la discrepancia (como un elemento
<time>o<span>). - Añade la prop
suppressHydrationWarning={true}al elemento afectado.
<p suppressHydrationWarning={true}>
Última visita: {new Date().toLocaleDateString()}
</p>
Nota: Utiliza este método con precaución, ya que solo enmascara advertencias menores de texto y no resuelve problemas estructurales profundos en el DOM.