¿Cómo recuperar datos del lado del servidor en la última versión de Next.js? Intenté getStaticProps pero no se ejecuta y queda indefinido

Resuelto victor asked hace 1 año • 3 respuestas

Estoy trabajando en Django Rest Framework con Next.js y no puedo obtener datos de la API. Tengo datos en esta url http://127.0.0.1:8000/api/campaignsy cuando visito la url veo los datos.

El problema es que cuando busco y consuelo los datos con Next.js, obtengo undefined. Además, cuando intento mapear los datos, aparece el error:

Error de tiempo de ejecución no controlado

Error: no se pueden leer las propiedades de indefinido (leyendo 'mapa')

Aquí está mi Index.jsarchivo donde se realiza la obtención de datos:

import React from 'react'

export default function Index ({data}) {
  console.log(data)
  return (
    <div>
      <main>
        <h1>Available Campaigns</h1>
        {data.map((element) => <div key={element.slug}>
          <div>
            <div>
              <img src={element.logo} height={120} width={100} alt="image" />
            </div>
            <div></div>
          </div>

        </div>)}
      </main>
    </div>
  );
}

export async function getStaticProps() {
  const response = await fetch("http://127.0.0.1:8000/api/campaigns");
  const data = await response.json();
  return {
    props: {
      data: data
    },
  }
}

Aquí hay una captura de pantalla de los datos que obtengo cuando visito la URL:

Imagen

Aquí está la estructura de archivos de la aplicación Next.js dentro del front-end:

Estructura de archivos

Además, tenga en cuenta que estoy usando la última versión de Next.js. Cualquier ayuda será muy apreciada. Gracias.

victor avatar May 17 '23 05:05 victor
Aceptado

Los métodos como getServerSidePropsy getStaticPropssirven para recuperar datos en el servidor, pero solo funcionan para los componentes de la página dentro de la pagescarpeta (la forma inicial de configurar rutas en Next.js).

Desde Next.js 13, en el appdirectorio (usado cuando responde sí a la última pregunta que se muestra en la imagen a continuación) tenemos Componentes del servidor , donde puede obtener datos directamente en el cuerpo del componente como se muestra en el siguiente fragmento de código (lea los comentarios):

ingrese la descripción de la imagen aquí

/*
  If you want to access headers or cookies while fetching data,
  you can use these functions:
*/
import { cookies, headers } from "next/headers";

/*
 If the below component is the default export of a `page.js` and you are using 
 dynamic routes, slugs will be passed as part of `params`, and 
 query strings are passed as part of `searchParams`.
*/
export default async function Component({ params, searchParams }) {
  /* 
    This request should be cached until manually invalidated.
    Similar to `getStaticProps`.
    `force-cache` is the default and can be omitted.
  */
  const staticData = await fetch(`https://...`, { cache: "force-cache" });

  /*
    This request should be refetched on every request.
    Similar to `getServerSideProps`.
  */
  const dynamicData = await fetch(`https://...`, { cache: "no-store" });

  /* 
    This request should be cached with a lifetime of 10 seconds.
    Similar to `getStaticProps` with the `revalidate` option.
  */
  const revalidatedData = await fetch(`https://...`, {
    next: { revalidate: 10 },
  });

  return "...";
}

Dicho esto, puede obtener datos sin fetch()usar ninguna biblioteca o incluso hablar directamente con su base de datos con un ORM, en cuyo caso puede usar Route Segment Config :

// layout.js OR page.js OR route.js 👈🏽

import prisma from "./lib/prisma";

/*
  Keep one of the possibilities shown below (there are more on the doc), 
  depending on your needs. 
*/

export const revalidate = 10; // If you want to revalidate every 10s
// OR
export const dynamic = "force-dynamic"; // If you want no caching at all
// ...

async function getPosts() {
  const posts = await prisma.post.findMany();
  return posts;
}

export default async function Page() {
  const posts = await getPosts();
  // ...
}
Youssouf Oumar avatar May 17 '2023 13:05 Youssouf Oumar

Esta pregunta de StackOverFlow ( No se puede usar GetStaticProp en Next.js 13 ) se cerró como un duplicado de esta pregunta.

Para ayudar a novatos como yo:

No puedes usar getStaticProps en Nextjs 13 (usando App Router).

La nueva forma es simplemente usar fetch. Puedes leer más sobre la recuperación aquí .

async function getArtist(username: string) {
  const res = await fetch(`https://api.example.com/artist/${username}`)
  return res.json()
}

Esta imagen compara la antigua y la nueva forma de hacer las cosas. fuente de imagen

ingrese la descripción de la imagen aquí

Debido a que el nuevo valor predeterminado es almacenar en caché todas las solicitudes de recuperación (a menos que opten por no participar), llamar a fetch en un componente estático tiene el mismo efecto que getStaticProps. Puede leer más sobre la obtención de datos estáticos aquí .

Para que quede claro, esta solicitud de recuperación normal:

//Similar to 'getStaticProps' when used in a static rendering component
fetch(API_URL)

es lo mismo que esta solicitud de 'forzar caché':

//This request would be cached until manually invalidated. 
//Similar to 'getStaticProps'
//Use this type of fetching for data that does not change often.
 
fetch(API_URL, { cache: 'force-cache' })

Más información sobre el almacenamiento en caché predeterminado aquí .

¿Por qué quisiste utilizar getStaticProps en primer lugar?

Para ayudar a los novatos, que encuentran getStaticPropsen un tutorial y encuentran el camino hasta aquí, la razón por la que desea utilizarlo getStaticPropses para representar una página una vez y luego enviarla a cada usuario.

Esto hace que su página sea más rápida, envíe menos código a sus usuarios y sea mejor para SEO, etc.

Pero, ¿qué pasa si necesitas obtener algunos datos para representar esa página una vez? Antes de Nextjs 13 usabas getStaticProps.

Ahora estás fetchen un componente estático. El efecto es el mismo.

Y ese efecto es que, una vez (en el momento de la compilación, cuando implementas tu proyecto), Nextjs obtendrá algunos datos, luego los usará para representar una página y luego enviará esa página pre-renderizada a todos los que la necesiten.

Si necesita generar estáticamente un montón de páginas usando rutas dinámicas, la generateStaticParamsfunción se puede usar para generar rutas en el momento de la compilación en lugar de bajo demanda en el momento de la solicitud para rutas dinámicas. información aquí .

Para los novatos, si no saben qué son las rutas dinámicas, simplemente usen fetch. :)

Joshua Dance avatar Jul 25 '2023 22:07 Joshua Dance

En el directorio de aplicaciones no puede utilizar métodos getServerSidePropssimilares para obtener datos. En lugar de esto, con el componente del servidor, puede hacer que el componente sea autoasincrónico y recuperar datos directamente en el cuerpo del componente. Además, puede pasar los datos al componente del cliente para prestar el servicio.getStaticPropsgetInitialProps

export async function getData(){
 const res = await fetchData();
 const data = res.json()
 
return data
}

Ahora puedes llamar a esta función asíncrona en tu componente principal.

export async function(){
   const data = await getData()
   return (<ClientComponent data />)
}
Ahsan Khan avatar Jun 12 '2023 14:06 Ahsan Khan