Estoy tratando de aprender nextjs. Luchando para resolver el enrutamiento con getServerSideProps .
Usando una API gratuita, tengo una lista de países que se muestran en el DOM. Quiero vincular dinámicamente a un país y que se obtengan y muestren datos para ese país específico.
Aquí está mi código hasta ahora
const Country = props => ( <Layout> <h1>{props.country.name}</h1> <span>{props.country.capital}</span> </Layout> ); export async function getServerSideProps(context) { const { id } = context.query; const res = await fetch(`https://restcountries.eu/rest/v2/name/${id}`); const country = await res.json(); console.log(`Fetched place: ${country.name}`); return { props: { country } }; } export default Country; <div className='container'> <Head> <title>Countries List</title> <link rel='icon' href='/favicon.ico' /> </Head> <Layout> <main> <h1> Countries{' '} <span role='img' aria-label='world emoji'> 🌎 </span> </h1> <ul> {countries.map(country => ( <li key={country.name}> <Link href='/p/[id]' as={`/p/${country.name}`}> <a>{country.name}</a> </Link> </li> ))} </ul> </main> </Layout> </div> ); export async function getServerSideProps() { // Call an external API endpoint to get posts. const res = await fetch('https://restcountries.eu/rest/v2/all'); const countries = await res.json(); // By returning { props: posts }, the Blog component // will receive `posts` as a prop at build time return { props: { countries, }, }; } export default Home; La URL enruta dinámicamente bien. Por ejemplo, cuando hace clic en Afganistán, la URL muestra http://localhost:3000/p/Afghanistan .
Sin embargo, el componente de mi país no muestra nada y se imprime undefined en la terminal.
Ejemplo de URL y respuesta de URL: https://restcountries.eu/rest/v2/name/Afghanistan
{ name: "Afghanistan" }Disculpas si es una pregunta de novato. Tratando de aprender nextjs
export async function getServerSideProps(context) { const { id } = context.query; const res = await fetch(`https://restcountries.eu/rest/v2/name/${id}`); const country = await res.json(); console.log(`Fetched place: ${country.name}`); return { props: { country } }; }está devolviendo un objeto anidado desde la función anterior
{ props: { country:country } }por lo que este accesorio se adjuntará a los accesorios de esta manera:
`props.props`así es como debes implementar
const Country = props => ( <Layout> <h1>{props.props.country.name}</h1> <span>{props.props.country.capital}</span> </Layout> ); En la versión anterior de next.js, creo que se actualizó después de la versión 9, no regresábamos de la función del lado del servidor mediante el uso de props . A partir de ahora, la forma correcta de implementación es
return { props: { countries, }, };Solo para agregar a la respuesta aceptada, también puede desestructurar para que sea (en mi humilde opinión) más legible. Aunque esto es totalmente opcional.
const Country = ({ country }) => ( <Layout> <h1>{country.name}</h1> <span>{country.capital}</span> </Layout> );No hay nada de malo en la forma en que maneja el enrutamiento dinámico de la página. El problema es que los datos devueltos por la API son una matriz, pero su código espera que sea un objeto . Puede recuperar el primer elemento de la matriz y pasarlo al componente desde getServerSideProps .
export async function getServerSideProps(context) { const { id } = context.params; // Use `context.params` to get dynamic params const res = await fetch(`https://restcountries.com/v2/name/${id}`); // Using `restcountries.com` as `restcountries.eu` is no longer accessible const countryList = await res.json(); const [country] = countryList; // Get first item in array returned from API return { props: { country } }; } const Country = ({ country }) => { console.log(country); return ( <> <h1>{country.name}</h1> <span>{country.capital}</span> </> ); }; export default Country;