2021鐵人賽
React
上一篇使用靜態的資料,將多張數據資料表畫成線圖呈現在網頁上,因為這個資料來源是JSON檔,所以是相對難更新的,因此本篇要將資料來源改為使用API串接取得,讓資料可以時時保持在最新狀態。
上一篇是在Charts元件中納入所有資料,所有圖表都是從Charts這一頁渲染的,其實如果往內觀察,每一張圖表都是相同的版型,因此可以將這個版型拉出來變成一個子元件,之後就可以重複使用,另外還有一個考量點是,當圖表數較多的時候,一次讀取所有資料會是很大的負擔,這個問題可以透過scroll down動態讀取圖表資料來解決,就不需要在頁面一載入的時候就讀取所有資料,對網頁載入速度上會有幫助。
上一篇的檔案架構
本篇的檔案架構
新增Card元件,代表每個圖表區域都是一張卡片
新增Card元件之後,串接API資料的功能就會是Card來處理,程式碼如下:
// 這邊會用到React的hook功能
import React, { useEffect, useState } from 'react';
import styles from './Card.module.css';
import Highcharts from 'highcharts/highstock';
import HighchartsReact from 'highcharts-react-official';
const Card = (props) => {
// 將圖表標題及共用的option寫成一個state
const [chartOption, setChartOption] = useState({
title: {
text: props.item.title
},
xAxis: {
type: "datetime",
title: {
text: 'Date'
}
}
});
// 抓取資料的function
const fetchData = (series_id) => {
// 打到自建的代理伺服器位址再透過轉址至目標位址,避免CORS
fetch(`${process.env.REACT_APP_PROXY_SERVER_URL}/series/observations?series_id=${series_id}&api_key=${process.env.REACT_APP_API_KEY}&file_type=json`, {
headers: {
'Target-URL': 'https://api.stlouisfed.org/fred'
}
})
.then((response) => response.json())
.then((data) => {
// 整理資料
let data1 = [];
data.observations.forEach(ob => {
data1.push([new Date(ob.date).getTime(), Number(ob.value)]);
});
// 將資料存至chartOption這個state
setChartOption((prevOption) => {
return {
...prevOption,
series: [
{
name: props.item.title,
data: data1
}
]
}
})
});
};
// 使用useEffect hook,讓網頁一載入就打資料,並且加入dependency避免進入infinite loop
useEffect(() => {
fetchData(props.item.series_id);
}, []);
return (
<div className={styles.chartFrame}>
<HighchartsReact
highcharts={Highcharts}
constructorType={'stockChart'}
options={chartOption}
/>
<div className={styles.chartInfo}>
<p className={styles.source}>source: {props.item.source}</p>
<p className={styles.date}>updated: {props.item.updated}</p>
</div>
<div>
<p className={styles.document}>{props.item.document}</p>
</div>
</div>
)
}
export default Card;
重新整理一下,打開DevTools確認Network的fetch事件狀態是200,表示有成功發送,圖也正常顯示,應該就OK了。
Card元件使用到蠻多技術的,包含:proxy server、useState hook、useEffect hook。接下來幾篇會詳細說明使用這些技術的原因。下一篇就先說明為什麼要用一個proxy server做中繼站吧。