This is my first time using NextJS and I'm trying to load 3 random dog breed images onto the app's webpage using the Dog.ceo API. I am able to see the three random dogs in the console from the console.log(data) line, but the images aren't being displayed. In this API there are only two properties - message (containing the image URL) and status (displaying 'success'). Any help in how to get these images to display? Also to note, I'm not using Typescript for this.
const defaultEndpoint = "https://dog.ceo/api/breeds/image/random/3";
export async function getServerSideProps() {
const res = await fetch(defaultEndpoint);
const data = await res.json();
return {
props: { data },
};
}
export default function Home({ data }) {
console.log("data", data);
const { results = [] } = data;
return (
<div className={styles.container}>
<Head>
<title>Dog Breed App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<div className="grid">
{results.map((result) => {
const { message } = result;
return (
<div key={message}>
<img src={message} alt=""></img>
</div>
);
})}
</div>
</main>
</div>
);
}
I tried using "message" from the "data" variable to get the url for the image. But that isn't working.
CodePudding user response:
It's just a destructuring error. You have const { results = [] } = data;
.
That line says: Find the property in my data object called results and if it doesn't exist, set it to an empty array. Your data object doesn't have a property called results
. It has a property called message
.
You could change this line to const { message = [] } = data
and then just loop over the message array or you could just store the message array in the props.data
property like this:
export async function getServerSideProps() {
const res = await fetch('https://dog.ceo/api/breeds/image/random/3');
// Destructure the response object here and
// rename the 'message' property as 'data'
const { message: data } = await res.json();
return {
props: { data },
};
}
// Destructure the props object to have access to the
// property named data:
export default function Home({ data }) {
return (
<main>
<div className="grid">
{data.map((img) => (
<div key={img}>
<img src={img} alt="dog"></img>
</div>
))}
</div>
</main>
);
}
CodePudding user response:
you can use useEffect
hook to load data and update to a state dogs
. This will update render once on component creation.
const defaultEndpoint = "https://dog.ceo/api/breeds/image/random/3";
import React, { useState, useEffect } from 'react'
export default function Home({ data }) {
const [dogs, setDogs] = useState([]);
export async function getServerSideProps() {
const res = await fetch(defaultEndpoint);
const data = await res.json();
console.log("data", data);
setDogs(data)
}
useEffect(() => {
getServerSideProps()
}, [])
return (
<div className={styles.container}>
<Head>
<title>Dog Breed App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<div className="grid">
{dogs.map((result) => {
const { message } = result;
return (
<div key={message}>
<img src={message} alt=""></img>
</div>
);
})}
</div>
</main>
</div>
);
}
I'll suggest using [dependencies]
in useEffect
to control when it re-renders it like below
useEffect(() => {
//
return () => {
//
}
}, [dependencies])