I am currently trying to map through every planet in the star wars api and print out the individual planet name but I am stuck. API LINK (https://swapi.dev/)
Thankyou for any help or advice
I tried using axios and Use Effect but am not sure where my errors may be. Below is what i have in my AllPlanets React Component.
`
import React from "react";
import axios from "axios";
import { useState, useEffect } from "react";
const AllPlanets = () => {
const [data, setData] = useState("");
useEffect(() => {
axios
.get(`https://swapi.dev/api/planets`)
.then((res) => setData(res.data))
.catch((error) => console.log(error));
});
return (
<div>
{data && (
<div className="flex">
{data.map((planet, idx) => (
<p>{planet.name}</p>
))}
</div>
)}
</div>
);
};
export default AllPlanets;
`
CodePudding user response:
These are the needed fixes (see comments in code as well):
- The API response contains the property
results
that has the actual list of planets - The
useEffect
needs an empty dependencies array to block it from running on each render, and creating an infinite loop - Each item in an rendered list needs a key with a unique value
const { useState, useEffect } = React;
const AllPlanets = () => {
const [data, setData] = useState("");
useEffect(() => {
axios
.get(`https://swapi.dev/api/planets`)
.then(res => setData(res.data.results)) // get the results property from the res.data object
.catch(error => console.log(error));
}, []); // add a dependency array so you won't have an infinite loop
return (
<div>
{data && (
<div className="flex">
{data.map(({ name }) => (
// use the name as key
<p key={name}>{name}</p>
))}
</div>
)}
</div>
);
};
ReactDOM
.createRoot(root)
.render(<AllPlanets />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.1.3/axios.min.js" integrity="sha512-0qU9M9jfqPw6FKkPafM3gy2CBAvUWnYVOfNPDYKVuRTel1PrciTj a9P3loJB j0QmN2Y0JYQmkBBS8W mbezg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="root"></div>
CodePudding user response:
If you console.log
the result you'll notice it's not an array of planets. It's an object with this structure:
{
count: 60
next: "https://swapi.dev/api/planets/?page=2"
previous: null
results: Array(10)
}
So replace
.then((res) => setData(res.data))
with
.then((res) => setData(res.data.results))
Alternatively, if you want to use next
and previous
provided links, for pagination, keep data
in the returned format and map its results
instead:
{data.results.map((planet, idx) => (
<p>{planet.name}</p>
))}
... and also make use of the previous and next links.
Here's an example:
https://codesandbox.io/s/wizardly-dirac-k7r1ek?file=/src/App.js