I'm currently trying to take data from an API so I can use it on my page. I'm programming with React and I am trying to use useEffect
with an async function.
Can someone please tell me why it breaks on a page refresh?
import React, { useEffect, useState } from 'react'
import axios from 'axios'
import './Cryptoinfo.css'
function Cryptoinfo() {
const [coinprice, setCoinprice] = useState([])
const url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur`
useEffect(() => {
async function fetchData() {
try {
const result = await axios.get(url)
setCoinprice(result.data.slice(0, 10))
console.log(result)
} catch (e) {
console.error(e)
}
}
fetchData()
}, [url])
return (
<>
<div className='crypto-info-container'>
<div className='name-pic'>
<h3 className='crypto-info-img'>O</h3>
<h3 className='crypto-info-name'>Name</h3> //this should be coinprice[0].name but it breaks if i do that.
</div>
<h3 className='crypto-info-price'>Price</h3>
<h3 className='crypto-info-mc'>Marketcap</h3>
<h3 className='crypto-info-vol'>Volume (24hr)</h3>
<h3 className='crypto-info-sup'>Circulating supply</h3>
</div>
</>
)
}
export default Cryptoinfo
CodePudding user response:
On the first time this component renders, the value of coinprice is []. When u try to get .name from it, it will break because u can't get.name from undefined value.
coinPrice[0] = undefined
coinprice[0].name = Uncaught TypeError
CodePudding user response:
you can try like this coinprice[0]?.name
or you have to put condition before html start like this {coinprice && ( ---HTML--- )};
hope it will help you.
CodePudding user response:
It was mentioned the issue is coinprice
was undefined
which is true so here is a ternary solution until the data is returned from the API:
return (
<>
<div className="crypto-info-container">
{coinprice.length === 0 || coinprice.length === undefined ? (
<h3 className="crypto-info-img">Loading</h3>
) : (
<>
<div className="name-pic">
<h3 className="crypto-info-img">O</h3>
<h3 className="crypto-info-name">Name</h3> //this should be coinprice[0]?.name but it
breaks if i do that.
</div>
<h3 className="crypto-info-price">Price</h3>
<h3 className="crypto-info-mc">Marketcap</h3>
<h3 className="crypto-info-vol">Volume (24hr)</h3>
<h3 className="crypto-info-sup">Circulating supply</h3>
</>
)}
</div>
</>
)
More about optional chaining so it's technically missing its just an option to get around the undefined
.
CodePudding user response:
Modify your code.
import React, { useEffect, useState } from "react";
import axios from "axios";
function Cryptowatch() {
const [data, setData] = useState([]);
const url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur&per_page=5`;
useEffect(() => {
async function fetchData() {
try {
const result = await axios.get(url);
setData(result.data);
console.log(data);
} catch (e) {
console.error(e);
}
}
fetchData();
}, []);
const cryptos = data.map((cryp) => {
return (
<div className="crypto-info-container">
<div className="name-pic">
<img src={data.image} className="crypto-info-img"></img>
<h3 className="crypto-info-name">{cryp.name}</h3>
</div>
<h3 className="crypto-info-price">{cryp.current_price}</h3>
<h3 className="crypto-info-mc">{cryp.market_cap}</h3>
<h3 className="crypto-info-vol">{cryp.total_volume}</h3>
<h3 className="crypto-info-sup">{cryp.total_supply}</h3>
</div>
);
});
return <>{data && cryptos}</>;
}
export default Cryptowatch;