Mejores Prácticas de Datos en Next.js
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de cada página en esta sección.
Busca en todas las páginas de la documentación
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de cada página en esta sección.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
await fetch(...) directamente en el cuerpo del Componente Server en lugar de usar useEffect - sin estado de carga, sin cascada del cliente, y los datos se envían como HTML.await produce un objeto Promise (a menudo renderizado como [object Promise]); siempre haz const { slug } = await params.const [user, posts] = await Promise.all([getUser(id), getPosts(id)]) - para que la latencia total sea igual a la llamada más lenta en lugar de la suma, y deja que TypeScript infiera la tupla de resultado de forma gratuita.const a = await getA(); const b = await getB(); para datos independientes - las promises comienzan en la creación, pero cada await sigue bloqueando la siguiente línea, produciendo latencia secuencial.Promise.allSettled impide que un único rechazo descarte los otros resultados exitosos y te permite renderizar una página parcial.fetch, por lo que envuelve funciones de base de datos y ORM - const getUser = cache((id: string) => db.user.findUnique({ where: { id } })) - para obtener deduplicación por renderizado en layouts y páginas.cache: "no-store" en cualquier lugar de una ruta opta toda la ruta al renderizado dinámico; muévelo a un componente separado envuelto en <Suspense> para que el resto pueda permanecer estático.cache: "auto" (no force-cache), por lo que establece cache o next.revalidate en cada fetch en lugar de confiar en lo que el framework infiera.fetch(url, { next: { tags: ["product-abc123"] } }) - usa cadenas con espacio de nombres en lugar de genéricas como "data" para que revalidateTag("product-abc123") no elimine silenciosamente cachés no relacionadas.revalidatePath/revalidateTag marcan el caché como obsoleto para la siguiente solicitud - la respuesta actual sigue devolviendo datos obsoletos, por lo que usa cache: "no-store" cuando necesitas datos frescos ahora mismo.revalidatePath("/") actualiza solo la página raíz; pasa "layout" - revalidatePath("/dashboard", "layout") - para invalidar el layout más cada página secundaria bajo él.unstable_cache(fn, keyParts, { tags, revalidate }) es la herramienta - pero asigna a cada llamada keyParts distintos y descriptivos o devolverás datos corruptos por colisiones de claves.router.refresh() (o ajusta experimental.staleTimes) para borrarlo.redirect() lanza un error centinela que Next.js captura para realizar la navegación; envolverlo en try/catch suprime la redirección, por lo que colócalo después de tu mutación y fuera de cualquier controlador de errores.(prevState, formData) => Promise<State> y conéctala a través de useActionState para que el estado pendiente y los mensajes de error fluyan a través de React de forma limpia.addOptimistic dentro de startTransition - startTransition(async () => { addOptimistic(newItem); await saveItem(newItem) }) - para que los usuarios vean el cambio al instante y la bandera pendiente siga controlando estados deshabilitados.<Suspense> para que los widgets se transmitan a medida que se resuelvan; un límite de nivel superior bloquea toda la página en la consulta más lenta y anula la transmisión.error.tsx o <ErrorBoundary>) al mismo nivel.useSearchParams() lanza un error durante la prerrenderización estática, por lo que el componente que lo lee debe estar dentro de un límite <Suspense> o la compilación fallará.router.push; usa router.replace para que el botón atrás regrese a una página anterior significativa y también reinicia page=1 cada vez que la consulta cambia.const token = (await cookies()).get("session")?.value - y tocar cualquiera hace que la ruta sea dinámica; léelos en un componente hoja pequeño bajo <Suspense> cuando quieras que el resto de la ruta permanezca estático.cookies() es de solo lectura en Componentes Server, por lo que las escrituras deben ocurrir en una Server Action, Route Handler, o Middleware - (await cookies()).set("session", token, { httpOnly: true, secure: true, sameSite: "lax" }).async function* más for await...of para mantener solo un lote en memoria, componer con ayudantes map/filter/take, y recuerda que los generadores son solo del servidor y de uso único.Revisado por Chris St. John·Última actualización: 16 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥