2021鐵人賽
React
上一篇確認過API內容之後,剩下的部份就是串接API,並將資料呈現在畫面上了,雖然描述起來是短短兩句,不過還是寫了好多的程式碼,下面就會挑兩個重點部份來說明。
在取得美國股市不同指數的收盤資料時,因為參數不同,每個指數都需要呼叫一次API,下面比較我剛開始的寫法跟後來非同步的寫法,速度差蠻多的。
const fetchCloseData = async () => {
# 指定資料起始日
let parse_date = new Date(today.valueOf() - 4 * 1000 * 60 * 60 * 24).toISOString().slice(0, 10);
# 一支API跑完再跑下一支
const DJI = await FinmindAPIUS({ dataset, data_id: "^DJI", start_date: parse_date, end_date: "" })
const GSPC = await FinmindAPIUS({ dataset, data_id: "^GSPC", start_date: parse_date, end_date: "" })
const IXIC = await FinmindAPIUS({ dataset, data_id: "^IXIC", start_date: parse_date, end_date: "" })
const SOX = await FinmindAPIUS({ dataset, data_id: "^SOX", start_date: parse_date, end_date: "" })
const VIX = await FinmindAPIUS({ dataset, data_id: "^VIX", start_date: parse_date, end_date: "" })
return ...
};
const fetchCloseData = async () => {
# 指定資料起始日
let parse_date = new Date(today.valueOf() - 4 * 1000 * 60 * 60 * 24).toISOString().slice(0, 10);
# 非同步執行
const [DJI, GSPC, IXIC, SOX, VIX] = await Promise.all([
FinmindAPIUS({ dataset, data_id: "^DJI", start_date: parse_date, end_date: "" }),
FinmindAPIUS({ dataset, data_id: "^GSPC", start_date: parse_date, end_date: "" }),
FinmindAPIUS({ dataset, data_id: "^IXIC", start_date: parse_date, end_date: "" }),
FinmindAPIUS({ dataset, data_id: "^SOX", start_date: parse_date, end_date: "" }),
FinmindAPIUS({ dataset, data_id: "^VIX", start_date: parse_date, end_date: "" }),
])
return ...
};
如下圖這兩個資料,之前有提到單一資料區塊已經有拉一個共用的UI模板出來,所以這張圖可以看成兩個類似的UI模板,不過其實又有些許的不同,加權指數那條有三個資料,而買賣超只有一個資料,但是我還是想讓他們共用一個UI就好,因為長相是類似的。
作法就是當收到的資料有包含spread,就表示它是上面那個樣子的模板,如果沒有,就是下面的模板,因此程式碼撰寫如下,透過判斷props傳進來的資料有哪些,去return適合的版型,不過看起來JSX的部份還是蠻冗長的就是了,時間有限,就先這樣子寫,有時間的話應該可以切更多子件,看起來會更簡潔一些。
src\UI\IndexCloseInfo\IndexCloseInfo.js
import React from 'react';
import styles from './IndexCloseInfo.module.css';
import { Col } from 'react-bootstrap';
const Card = (props) => {
# 有spread資料
if (props.data && props.data.close.spread) {
return (
<Col sm={12} md={6} lg={4} xl={3} xxl={3} className={styles.bar}>
<div className={styles.bar_left_side}>
<div className={styles.bar_icon}>{props.data.info.iconText}</div>
</div>
<div className={styles.bar_right_side}>
<p className={styles.bar_text}>{props.data.info.name}</p>
<div className={styles.bar_data_group}>
<p className={`${styles.bar_data} ${props.data.close.spread > 0 && props.data.close.spread !== 0 ? styles.red_text : styles.green_text}`}>{props.data.close.price}</p>
<p className={styles.bar_data}>|</p>
<p className={`${styles.bar_data} ${props.data.close.spread > 0 && props.data.close.spread !== 0 ? styles.red_text : styles.green_text}`}>{props.data.close.spread}</p>
<p className={styles.bar_data}>|</p>
<p className={`${styles.bar_data} ${props.data.close.spread > 0 && props.data.close.spread !== 0 ? styles.red_text : styles.green_text}`}>
{
Math.round(props.data.close.spread * 10000 / (props.data.close.price - props.data.close.spread)) / 100
}
%
</p>
</div>
</div>
</Col >
)
# 沒有spread資料
} else if (props.data && !props.data.close.spread) {
return (
<Col sm={12} md={6} lg={4} xl={3} xxl={3} className={styles.bar}>
<div className={styles.bar_left_side}>
<div className={styles.bar_icon}>{props.data.info.iconText}</div>
</div>
<div className={styles.bar_right_side}>
<p className={styles.bar_text}>{props.data.info.name}</p>
<div className={styles.bar_data_group}>
<p className={`${styles.bar_data} ${props.data.close.price > 0 && props.data.close.price !== 0 ? styles.red_text : styles.green_text}`}>{+(Math.round(props.data.close.price / 100000000 + "e+2") + "e-2")}億</p>
</div>
</div>
</Col >
)
# 沒有任何資料
} else {
return <p>No data</p>
}
};
export default Card;
其實剛開始寫的時候,沒有想到首頁的程式碼會有這麼多,有一部分的原因可能是因為無法改變API的內容,所以需要寫一些整理資料的程式,雖然畫面處理的速度可能有點慢,不過還是成功串接了API,並隨時顯示最新資料,蠻有成就感的。