Skip to content

FOOR29/nextjs-15-data-fetching-guide

Repository files navigation

Next.js 15 Data Fetching Guide

Guía completa sobre data fetching en Next.js 15 con App Router

📚 Contenido

  • Static Generation (getStaticProps equivalente)
  • Server-Side Rendering (getServerSideProps equivalente)
  • Incremental Static Regeneration (ISR)
  • generateStaticParams (getStaticPaths equivalente)
  • Ejemplos prácticos con APIs reales

🚀 Tecnologías

  • Next.js 15
  • TypeScript
  • Tailwind CSS
  • DummyJSON API

📖 Ejemplos Incluidos

  • Lista de productos con generación estática
  • Rutas dinámicas con [id]
  • ISR con revalidación automática
  • Dashboard dinámico con autenticación




Cambio Importante en Next.js 15

getStaticProps, getServerSideProps y getStaticPaths son funciones del Pages Router (el sistema antiguo de Next.js). En Next.js 15 con el App Router (que es la versión actual), estas funciones ya no existen como tal. El data fetching ahora se hace directamente dentro de los componentes de servido

Por qué no te funcionó ahora?

En el Pages Router (versión antigua), estas funciones debían estar en archivos dentro de la carpeta pages/. Pero en Next.js 15 con App Router, trabajas con la carpeta app/ y el sistema es completamente diferente

Los 3 Métodos Equivalentes en Next.js 15

Server Components (reemplazo de getStaticProps y getServerSideProps) En Next.js 15, puedes hacer fetch directamente en los componentes de servidor:

// app/pokemon/page.tsx
export default async function PokemonPage() {
  // Fetch directo - se ejecuta en el servidor
  const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20');
  const data = await res.json();

  return (
    <div>
      <h1>Pokémon List</h1>
      <ul>
        {data.results.map((pokemon: any) => (
          <li key={pokemon.name}>{pokemon.name}</li>
        ))}
      </ul>
    </div>
  );
}

Este componente es estático por defecto (similar a getStaticProps)

Opciones de cache en fetch

Para controlar el comportamiento (estático vs dinámico):

// Comportamiento estático (como getStaticProps)
const res = await fetch('https://api.com/data', { 
  cache: 'force-cache' // cachea indefinidamente
});

// Comportamiento dinámico (como getServerSideProps)
const res = await fetch('https://api.com/data', { 
  cache: 'no-store' // sin cache, siempre fresh
});

ISR - Incremental Static Regeneration

ISR permite regenerar páginas estáticas después del build sin reconstruir todo el sitio. Es ideal para contenido que cambia poco pero necesita actualizarse ocasionalmente:

// app/characters/[id]/page.tsx
const CharacterPage = async ({ params }: { params: { id: string } }) => {

    const res = await fetch(
        `https://rickandmortyapi.com/api/character/${params.id}`,
        {
            next: { revalidate: 60 } // se regenera cada 60s
        }
    );
    const characater = await res.json();

    return (
        <div>
            <h1>{characater.name}</h1>
            <p>Status: {characater.status}</p>
        </div>
    )
}

export default CharacterPage

Cuándo Usar Cada Método

Fetch con cache: 'force-cache' (Estático)

  • Contenido que no cambia o cambia muy raramente

  • Blogs, documentación, páginas de marketing

  • Ventajas: SEO excelente, velocidad máxima

  • Ejemplo: Lista de categorías fijas

Fetch con cache: 'no-store' (Dinámico)

  • Contenido específico del usuario (dashboards, perfiles)

  • Datos que cambian constantemente

  • Ventajas: Siempre actualizado

  • Desventajas: Más lento, más carga en el servidor

  • Ejemplo: Carrito de compras, notificaciones

ISR con revalidate (Regeneración Incremental)

  • Contenido que se actualiza periódicamente

  • Catálogos de productos, feeds de noticias

  • Ventajas: Balance entre velocidad y frescura

  • Ejemplo: Lista de Pokémon que se actualiza cada hora

Ejemplo Completo con Rick and Morty API

// app/characters/page.tsx - Lista con ISR
export default async function CharactersPage() {
  const res = await fetch(
    'https://rickandmortyapi.com/api/character',
    { next: { revalidate: 3600 } } // Regenera cada hora
  );
  const data = await res.json();

  return (
    <div>
      <h1>Rick and Morty Characters</h1>
      <div>
        {data.results.map((char: any) => (
          <div key={char.id}>
            <h2>{char.name}</h2>
            <p>{char.species}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

Para Base de Datos Futura

Cuando uses una base de datos (Prisma, Drizzle, etc.), el mismo principio aplica:

const ProductsPage = () => {
    // consulta directa en el server components
    const products = await db.product.findMany({
        where: { active: true }
    })

    return (
        <div>
            {products.map(product => {
                return (
                    <div key={product.id}>{product.name}</div>
                )
            })}
        </div>
    )
}

export default ProductsPage

Puedes controlar el caching usando unstable_cache de Next.js o las opciones de fetch para APIs externas

Client Components

Para datos en el cliente (interactividad, datos específicos del usuario después del render inicial), usa 'use client' con SWR o React Query:

'use client';
import useSWR from 'swr';

const fetcher = (url: string) => fetch(url).then(r => r.json());

export default function ClientPokemon() {
  const { data, error, isLoading } = useSWR(
    'https://pokeapi.co/api/v2/pokemon',
    fetcher
  );

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error</div>;

  return <div>{/* render data */}</div>;
}

Este enfoque es útil para datos que necesitan actualizarse sin recargar la página.​

Resumen

En Next.js 15 ya no usas getStaticProps, getServerSideProps ni getStaticPaths directamente. En su lugar, haces fetch dentro de Server Components y controlas el comportamiento con las opciones de cache. ISR se logra con la opción revalidate en el fetch.​

Ir a la clase 2

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors