I have a problem while creating my react app. I'm fetching data from CoinGecko API to build a crypto tracking app, but when I pass the data
prop from the parent App.js
to the child Info.js
. When I try to render the page it gives me Info.js:45 Uncaught TypeError: Cannot read properties of undefined (reading 'large')
. I really don't understand why it happens.
App.js
function App() {
const [isToggled, setIsToggled] = useState(false);
const [data, setData] = useState({});
const [coin, setCoin] = useState("bitcoin");
const getData = () => {
axios({
method: "GET",
url: `https://api.coingecko.com/api/v3/coins/${coin}?localization=en`,
})
.then((response) => {
console.log(response.data);
setData(response.data);
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
getData(coin);
}, []);
return (
<div>
<HeaderContainer />
<Search getData={getData} coin={coin} setCoin={setCoin} />
<Info mcap={mcap} data={data} />
</div>
);
}
Info.js
function Info({ image, mcap, data }) {
return (
<div className="info-container">
<div className="left-column">
<div className="top-row">
<div className="coin-icon-container">
<img
className="coin-icon"
src={data.image.large}
alt="coin logo"
width="40px"
height="40px"
></img>
</div>
<div className="coin-name-container">
<p className="coin-name">{data.name}</p>
<p className="coin-abbr">{data.symbol}</p>
</div>
<div className="coin-MCAP-details">
<p className="coin-position">#{data.market_cap_rank}</p>
<p className="coin-MCAP">{data.market_data.market_cap.usd}</p>
</div>
The same error happens with the market cap in the second to last line of code. data.name
and data.symbol
render correctly.
The response.json
file is very long, so i'll just put the important parts:
Response.json
{
"id": "bitcoin",
"symbol": "btc",
"name": "Bitcoin",
"asset_platform_id": null,
.......
"image":{
"thumb": "https://assets.coingecko.com/coins/images/1/thumb/bitcoin.png?1547033579",
"small": "https://assets.coingecko.com/coins/images/1/small/bitcoin.png?1547033579",
"large": "https://assets.coingecko.com/coins/images/1/large/bitcoin.png?1547033579"
}
.........
}
CodePudding user response:
SetData
is by default an empty object, and because Axios request is called in useEffect
. On the first render Info
component receives empty data
object.
To way to solve it.
- Add Loading state.
- Or Add Optional chaining (data?.image?.large)