I have a nested object which is a little complicated since it has numeric value as ID of each entry.
"coins":
0:{...}29 items
1:{...}29 items
2:{...}29 items
3:{...}29 items
4:{...}29 items
This is my code, this is not working for me. Console log is returning data but the UI component is not being rendered
import React, { useState, useEffect } from "react";
import "./Homepage.css";
import CryptoCard from "../Card/Card";
import axios from "axios";
const Homepage = () => {
const [coinData, setCoinData] = useState([], () => {
const localData = localStorage.getItem("coinData");
return localData ? JSON.parse(localData) : [];
});
useEffect(() => {
const options = {
method: "GET",
url: "https://coinranking1.p.rapidapi.com/coins",
headers: {
"x-rapidapi-host": "coinranking1.p.rapidapi.com",
"x-rapidapi-key": "API_KEY",
},
};
axios
.request(options)
.then((response) => {
setCoinData(response.data.data.coins);
// persist in localStorage
localStorage.setItem(
"coinData",
JSON.stringify(response.data.data.coins)
);
})
.catch((error) => {
console.error(error);
});
}, []);
console.log("Coins names");
coinData.forEach(function (coin) {
console.log(coin.name);
});
const i = 0;
return (
<div className="homepage">
<div className="heading">
<h1>Discover</h1>
<hr className="line" />
</div>
<div className="cards-container">
{coinData?.forEach(function (coin) {
<CryptoCard
name={coin.name}
coinUrl={coin.websiteUrl}
duration="4 minutes ago"
symbol={coin.symbol}
rank={coin.rank}
exchanges={coin.numberOfExchanges}
price={coin.price}
/>;
})}
{/* <CryptoCard
name={coinData[0]?.name}
coinUrl={coinData[0]?.websiteUrl}
duration="4 minutes ago"
symbol={coinData[0]?.symbol}
rank={coinData[0]?.rank}
exchanges={coinData[0]?.numberOfExchanges}
price={coinData[0]?.price}
/> */}
</div>
</div>
);
};
export default Homepage;
I need to iterate over this and return the data from each entry into my React component and I can not figure out how to iterate over them without a loop. Using loop does not work either for me.
CodePudding user response:
In react you don't have to use forEach. Instead you have to use .map
which is easy, declarative and do not mutate the original Array. With forEach
if you alter some member of the coin value inside the loop, or even in the CryptoCard
component, you are mutating the original array, which means mutate the react state, that's not allowed. But for this to work, please make sure to console log the coinData
variable and check if it contains the value you expect.
{coinData?.forEach(function (coin) {
<CryptoCard
name={coin.name}
coinUrl={coin.websiteUrl}
duration="4 minutes ago"
symbol={coin.symbol}
rank={coin.rank}
exchanges={coin.numberOfExchanges}
price={coin.price}
/>;
})}
should be
{(coinData|| []).map(coin => (
<CryptoCard
name={coin.name}
coinUrl={coin.websiteUrl}
duration="4 minutes ago"
symbol={coin.symbol}
rank={coin.rank}
exchanges={coin.numberOfExchanges}
price={coin.price}
/>;
))}
CodePudding user response:
You can do as follows:
{coinData?.map((coin) =>
<CryptoCard
name={coin.name}
coinUrl={coin.websiteUrl}
duration="4 minutes ago"
symbol={coin.symbol}
rank={coin.rank}
exchanges={coin.numberOfExchanges}
price={coin.price}
/>;
)}
.map
will then return a list of your CryptoCard
component.
CodePudding user response:
If the console.log
statements are printing the intended values properly and the following snippet is not working,
<div className="cards-container">
{coinData?.forEach(function (coin) {
<CryptoCard
name={coin.name}
coinUrl={coin.websiteUrl}
duration="4 minutes ago"
symbol={coin.symbol}
rank={coin.rank}
exchanges={coin.numberOfExchanges}
price={coin.price}
/>;
})}
</div>
It might be because you are not returning anything from inside the function inside the forEach
loop. Try adding return
before the component inside the function, like so
{coinData?.forEach(function (coin) {
return (
<CryptoCard
name={coin.name}
coinUrl={coin.websiteUrl}
duration="4 minutes ago"
symbol={coin.symbol}
rank={coin.rank}
exchanges={coin.numberOfExchanges}
price={coin.price}
/>;
)
})}