BaliseTonSite

Data Fetching

Récupère des données depuis n'importe où. Serveur, API, base de données... Next.js gère tout.

5.1Fetch dans un Server Component

Le plus beau avec les Server Components : tu peux utiliser fetch ou async/await directement dans ton composant. Pas besoin de useEffect, pas besoin de state de chargement.

TSXtsx
// app/blog/page.tsx (Server Component)

interface Article {
  id: number
  title: string
  body: string
}

export default async function BlogPage() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const articles: Article[] = await res.json()

  return (
    <main>
      <h1>Mon blog</h1>
      <ul>
        {articles.slice(0, 5).map((article) => (
          <li key={article.id}>
            <h2>{article.title}</h2>
            <p>{article.body.slice(0, 100)}...</p>
          </li>
        ))}
      </ul>
    </main>
  )
}

C'est tout. Pas de useState, pas de useEffect, pas de loading à gérer à la main. Le composant est async, il attend les données, et rend le HTML directement. L'utilisateur reçoit une page complète.

5.2Le cache intelligent

Next.js est malin avec les requêtes. Par défaut, les résultats de fetch sont mis en cache. Ça veut dire que si deux visiteurs demandent la même page, Next.js ne refait pas le fetch : il sert le résultat du cache.

Tu peux contrôler ce comportement :

TSXtsx
// Données toujours fraîches (pas de cache)
const res = await fetch('https://api.example.com/data', {
  cache: 'no-store'
})

// Revalider toutes les 60 secondes
const res = await fetch('https://api.example.com/data', {
  next: { revalidate: 60 }
})
OptionComportementCas d'usage
Par défautCache permanentContenu statique (pages marketing)
cache: 'no-store'Jamais de cacheDonnées temps réel (cours de bourse)
next: { revalidate: 60 }Cache + refresh toutes les 60sBlog, catalogue (bon compromis)

5.3Server Actions : les formulaires nouvelle génération

Les Server Actions, c'est la fonctionnalité qui change tout pour les formulaires. Au lieu de créer une API, de faire un fetch POST côté client, de gérer l'état de chargement... tu écris une fonction serveur et tu la branches directement sur ton formulaire.

TSXtsx
// app/contact/page.tsx

export default function ContactPage() {
  async function envoyerMessage(formData: FormData) {
    'use server'

    const nom = formData.get('nom')
    const message = formData.get('message')

    // Ici tu peux sauvegarder en BDD, envoyer un email...
    console.log(`Message de ${nom}: ${message}`)
  }

  return (
    <form action={envoyerMessage}>
      <input name="nom" placeholder="Ton nom" required />
      <textarea name="message" placeholder="Ton message" required />
      <button type="submit">Envoyer</button>
    </form>
  )
}

La directive 'use server' dans la fonction dit à Next.js : "Cette fonction tourne sur le serveur." Le formulaire l'appelle directement, sans API intermédiaire. C'est magiquement simple.

5.4Récupérer des données dynamiques par route

La combinaison route dynamique + fetch est ultra puissante. Par exemple, une page produit :

TSXtsx
// app/produits/[id]/page.tsx

interface Produit {
  id: number
  title: string
  price: number
  description: string
}

export default async function ProduitPage({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params
  const res = await fetch(`https://fakestoreapi.com/products/${id}`)
  const produit: Produit = await res.json()

  return (
    <main>
      <h1>{produit.title}</h1>
      <p>{produit.description}</p>
      <p className="text-2xl font-bold">{produit.price} €</p>
    </main>
  )
}

Chaque URL (/produits/1, /produits/42) affiche le bon produit. La donnée est récupérée côté serveur, le HTML est envoyé complet au navigateur. L'utilisateur voit le contenu instantanément.

5.5Gérer le chargement avec loading.tsx

Si le fetch prend du temps, rappelle-toi : tu peux créer un fichier loading.tsx dans le même dossier. Next.js l'affiche automatiquement pendant que les données arrivent.

TSXtsx
// app/produits/[id]/loading.tsx

export default function Loading() {
  return (
    <div className="animate-pulse">
      <div className="h-8 bg-slate-200 rounded w-3/4 mb-4" />
      <div className="h-4 bg-slate-200 rounded w-full mb-2" />
      <div className="h-4 bg-slate-200 rounded w-2/3" />
    </div>
  )
}

Ce "skeleton" (squelette grisé) donne l'impression que la page charge vite, même si le serveur est en train de récupérer les données. C'est une très bonne pratique UX.

Verifie tes acquis

5 questions pour valider ce chapitre

1. Comment faire un appel API dans un Server Component 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