BaliseTonSite

Erreurs React & Next.js

Les boss de donjon : hydration, SSR, build errors.

5.1Hydration Error : le boss le plus fourbe

L'erreur d'hydratation se produit quand le HTML genere par le serveur ne correspond pas a ce que React genere cote client. C'est comme si le plan du donjon changeait entre deux visites.

Les causes classiques d'erreur d'hydratationtsx
// CAUSE 1 : Utiliser Date() ou Math.random() dans le render
// Le serveur genere une valeur, le client en genere une autre
function BadComponent() {
  return <p>Il est {new Date().toLocaleString()}</p> // Hydration error !
}

// FIX : useEffect pour les valeurs dynamiques
function GoodComponent() {
  const [time, setTime] = useState("")
  useEffect(() => setTime(new Date().toLocaleString()), [])
  return <p>Il est {time}</p>
}

// CAUSE 2 : Balises mal imbriquees
// <p> ne peut pas contenir <div>
function Bad() {
  return <p><div>Contenu</div></p> // Hydration error !
}

// CAUSE 3 : Extensions navigateur qui modifient le DOM
// Solution : verifier en navigation privee

5.2"use client" : la frontiere serveur/client

Erreurs liees a use clienttsx
// ERREUR : utiliser useState dans un Server Component
// app/page.tsx (Server Component par defaut)
import { useState } from 'react' // Erreur au build !

export default function Page() {
  const [count, setCount] = useState(0) // Hooks = client only !
  return <p>{count}</p>
}

// FIX : ajouter 'use client' OU extraire dans un composant client
// components/Counter.tsx
'use client'
import { useState } from 'react'
export function Counter() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}

// app/page.tsx (reste Server Component)
import { Counter } from '@/components/Counter'
export default function Page() {
  return <Counter />
}

5.3Build errors : le gardien du deploiement

Le build est le gardien final. Il est plus strict que npm run dev : ce qui passe en dev peut echouer au build.

Erreurs de build les plus courantesbash
# ERREUR 1 : Type manquant
# "Type error: Property 'name' does not exist on type..."
# -> Tu as un typo ou un type incorrect. Verifie tes interfaces.

# ERREUR 2 : Import manquant ou circulaire
# "Module not found: Can't resolve './component'"
# -> Verifie le chemin relatif et l'export du fichier.

# ERREUR 3 : Dynamic import avec SSR
# "window is not defined"
# -> Le code accede a window dans un Server Component.

# ERREUR 4 : generateStaticParams manquant
# "Error: Page with dynamic route /[slug] requires generateStaticParams"
# -> Ajoute la fonction generateStaticParams dans ton page.tsx

5.4window is not defined (SSR)

window, document et localStorage n'existent pas cote serveur. Si tu les utilises dans un Server Component ou au top-level d'un module, ca plante.

Fix : acceder a window dans Next.jstsx
// ERREUR : au top-level du module
const theme = localStorage.getItem('theme') // ReferenceError: localStorage is not defined

// FIX 1 : dans un useEffect (composant client)
'use client'
import { useState, useEffect } from 'react'

function ThemeProvider() {
  const [theme, setTheme] = useState('light')

  useEffect(() => {
    const saved = localStorage.getItem('theme')
    if (saved) setTheme(saved)
  }, [])

  return <div data-theme={theme}>...</div>
}

// FIX 2 : guard typeof window
const isClient = typeof window !== 'undefined'
const theme = isClient ? localStorage.getItem('theme') : 'light'

5.5"async Server Component"

Erreurs de fetch dans les Server Componentstsx
// Dans Next.js 15+, les Server Components PEUVENT etre async
// Mais les Client Components ne le peuvent PAS

// OK : Server Component async
export default async function Page() {
  const data = await fetch('https://api.example.com/data')
  const json = await data.json()
  return <div>{json.title}</div>
}

// ERREUR : Client Component async
'use client'
export default async function Page() { // Interdit !
  const data = await fetch('/api/data')
  return <div>{data}</div>
}

// FIX : utiliser useEffect dans un Client Component
'use client'
export default function Page() {
  const [data, setData] = useState(null)
  useEffect(() => {
    fetch('/api/data').then(r => r.json()).then(setData)
  }, [])
  return <div>{data?.title}</div>
}

5.6Le guide anti-boss

BossSymptomeSolution
Hydration errorHTML serveur != clientuseEffect pour valeurs dynamiques
Hooks in SCuseState dans Server ComponentAjouter 'use client'
window undefinedlocalStorage/window en SSRGuard typeof window ou useEffect
Build type errorTypes incorrectsVerifier interfaces TS
Async clientasync dans 'use client'Utiliser useEffect + useState

Verifie tes acquis

5 questions pour valider ce chapitre

1. Quelle est la cause la plus courante d'une erreur d'hydratation Next.js ?

Valide et sauvegarde ce chapitre

Ne perds pas le fil de ton apprentissage. Chaque QCM terminé sauvegarde ton score. Crée ton profil gratuitement pour débloquer toutes les évaluations du site et retrouver tes résultats plus tard.

Commencer l'aventure
Déjà membre ?Connecte-toi