[英]Pushing API Data into Chart.js
我試圖將我的 API 數據推送到我的圖表中,但數據更新時間與圖表呈現時間似乎存在問題。 我正在控制台記錄我的兩個 arrays,它沒有在數組中顯示任何內容。 有誰知道我需要更改什么才能將我的數據更新到 state,然后再使用該數據呈現圖表?
function SmallBox(props) {
const [chartNums, setChartNums] = useState([])
const [chartLabels, setChartLabels] = useState([])
const [chartData, setChartData] = useState({})
const x = [];
const y = [];
const fetchData = async () => {
await fetch(`https://api.coingecko.com/api/v3/coins/${props.id}/market_chart?vs_currency=usd&days=1`)
.then((response) => {
return response.json();
})
.then((data) => {
for (let i = 0; i < data.prices.length; i++){
x.push(data.prices[i][0])
setChartLabels(x)
}
for (let i = 0; i < data.prices.length; i++){
y.push(data.prices[i][1])
setChartNums(y)
}
})
};
const chart = async () => {
await fetchData()
console.log(chartNums)
console.log(chartLabels)
setChartData({
labels: chartLabels,
datasets: [
{
label: '$',
data: chartNums,
backgroundColor: ['rgba(0,0,0,0.09)'],
borderColor: `${props.color}`,
borderWidth: 4,
borderJoinStyle: 'round',
borderCapStyle: 'round',
borderWidth: 3,
pointRadius: 0,
pointHitRadius: 10,
lineTension: .2,
}
]
})
}
useEffect(() =>{
chart();
}, []);
return (
<div id={props.id} className="smallBox">
<div className="smallBox_info">
<img className="smallBox-icon" src={props.image} alt={props.symbol}/>
<h2>{props.title}</h2>
</div>
<div className="smallBox_numbers">
<h2 className="smallBox-price">$ {props.currentPrice}</h2>
<h5 className="smallBox-roc">{props.percentChange}</h5>
</div>
<div className="smallBox_graph">
<Line data={chartData} options={{
responsive: true,
maintainAspectRatio: false,
title: {text: 'ThickBoyz', display: false},
legend: {display: false},
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
scales: {
xAxes: [{
display: false,
gridLines: {}
}],
yAxes: [{
display: false,
gridLines: {}
}]
},
tooltips: {
callbacks: {
//This removes the tooltip title
title: function() {}
},
//this removes legend color
displayColors: false,
yPadding: 10,
xPadding: 10,
position: 'nearest',
caretSize: 10,
backgroundColor: 'rgba(255,255,255,.9)',
bodyFontSize: 15,
bodyFontColor: '#303030'
}
}}/>
</div>
</div>
)
}
export default SmallBox
正確使用 async-await,不要將 promise then 方法與 await 混合使用。
import React, { useEffect, useState, useCallback } from "react";
import { Line } from "react-chartjs-2";
import "./styles.css";
export default function App() {
const [chartNums, setChartNums] = useState([]);
const [chartLabels, setChartLabels] = useState([]);
const [chartData, setChartData] = useState({});
const x = [];
const y = [];
const props = {
id: "bitcoin"
};
const fetchData = useCallback(async () => {
const response = await fetch(
`https://api.coingecko.com/api/v3/coins/${props.id}/market_chart?vs_currency=usd&days=1`
);
const data = await response.json();
if (data && data.prices) {
console.log(data.prices);
for (let i = 0; i < data.prices.length; i++) {
x.push(data.prices[i][0]);
setChartLabels(x);
}
for (let i = 0; i < data.prices.length; i++) {
y.push(data.prices[i][1]);
setChartNums(y);
}
}
}, [props]);
const chart = useCallback(async () => {
await fetchData();
console.log(chartNums);
console.log(chartLabels);
setChartData({
labels: chartLabels,
datasets: [
{
label: "$",
data: chartNums,
backgroundColor: ["rgba(0,0,0,0.09)"],
borderColor: `${props.color}`,
borderWidth: 4,
borderJoinStyle: "round",
borderCapStyle: "round",
pointRadius: 0,
pointHitRadius: 10,
lineTension: 0.2
}
]
});
}, [chartNums, chartLabels, fetchData, props.color]);
useEffect(() => {
chart();
}, [chart]);
return (
<div id={props.id} className="smallBox">
<div className="smallBox_info">
<img className="smallBox-icon" src={props.image} alt={props.symbol} />
<h2>{props.title}</h2>
</div>
<div className="smallBox_numbers">
<h2 className="smallBox-price">$ {props.currentPrice}</h2>
<h5 className="smallBox-roc">{props.percentChange}</h5>
</div>
<div className="smallBox_graph">
<Line
data={chartData}
options={{
responsive: true,
maintainAspectRatio: false,
title: { text: "ThickBoyz", display: false },
legend: { display: false },
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
scales: {
xAxes: [
{
display: false,
gridLines: {}
}
],
yAxes: [
{
display: false,
gridLines: {}
}
]
},
tooltips: {
callbacks: {
//This removes the tooltip title
title: function () {}
},
//this removes legend color
displayColors: false,
yPadding: 10,
xPadding: 10,
position: "nearest",
caretSize: 10,
backgroundColor: "rgba(255,255,255,.9)",
bodyFontSize: 15,
bodyFontColor: "#303030"
}
}}
/>
</div>
</div>
);
}
沙盒鏈接 - https://codesandbox.io/s/chartjs-fetchapidata-r3ghc?file=/src/App.js
考慮堅持使用.then()
語法或async/await
。 我建議使用后者,這應該使事情更簡單:
const fetchData = async () => {
const response = await fetch(`https://api.coingecko.com/api/v3/coins/1/market_chart?vs_currency=usd&days=1`)
const data = await response.json()
data.prices.forEach(price => {
x.push(price[0])
setChartLabels(x)
y.push(price[1])
setChartNums(y)
});
}
接下來,考慮您是否真的需要將chartLabels
和chartNums
存儲在 React state 中——它們沒有在您的 JSX 中使用,因此將它們作為普通的舊變量返回可能更清楚:
const fetchData = async () => {
const response = await fetch(`https://api.coingecko.com/api/v3/coins/1/market_chart?vs_currency=usd&days=1`)
const data = await response.json()
chartLabels = data.prices.map(price => price[0])
chartNums = data.prices.map(price => price[1]
return [chartLabels,chartNums]
}
然后后來,
const [chartLabels, chartNums] = await fetchData()
const [chartLabels, setChartLabels] = useState([]);
const [chartData, setChartData] = useState({});
const x = [];
const y = [];
const props = {
id: "bitcoin"
};
const fetchData = useCallback(async () => {
const response = await fetch(
`https://api.coingecko.com/api/v3/coins/${props.id}/market_chart?vs_currency=usd&days=1`
);
const data = await response.json();
if (data && data.prices) {
console.log(data.prices);
for (let i = 0; i < data.prices.length; i++) {
x.push(data.prices[i][0]);
setChartLabels(x);
}
for (let i = 0; i < data.prices.length; i++) {
y.push(data.prices[i][1]);
setChartNums(y);
}
}
}, [props,x,y]);
參考上面提供的解決方案,您可以初始化 x 和 y arrays 包裝 useMemo Hook 以返回更優化的解決方案並防止這樣的警告
專業提示:如果您不正確地添加依賴項或根本沒有添加依賴項,重復的 API 調用可能會讓您被阻止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.