用React刻自己的投资Dashboard Day6 - 建立图表区元件,串接API取得数据

tags: 2021铁人赛 React

上一篇使用静态的资料,将多张数据资料表画成线图呈现在网页上,因为这个资料来源是JSON档,所以是相对难更新的,因此本篇要将资料来源改为使用API串接取得,让资料可以时时保持在最新状态。

建立可以重复使用的子元件

上一篇是在Charts元件中纳入所有资料,所有图表都是从Charts这一页渲染的,其实如果往内观察,每一张图表都是相同的版型,因此可以将这个版型拉出来变成一个子元件,之後就可以重复使用,另外还有一个考量点是,当图表数较多的时候,一次读取所有资料会是很大的负担,这个问题可以透过scroll down动态读取图表资料来解决,就不需要在页面一载入的时候就读取所有资料,对网页载入速度上会有帮助。

  • 上一篇的档案架构

  • 本篇的档案架构

    新增Card元件,代表每个图表区域都是一张卡片

串接API取得资料

新增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做中继站吧。


<<:  Day_09 有线网路应用(二)

>>:  论解决问题的爽度XD

Day 17 (Ps)

1.笔刷填色 (云对话框) (影片Ps7) (1)选云图层Ctrl(载入选取)>选前景色>...

EP07 - Jenkins Pipeline 整合 Gitlab 使用 Webhook

将专案整合 Gitlab 和 Jenkins 产生 Token 前几天有在虚拟机械中产生金钥 今天也...

[JS] You Don't Know JavaScript [Scope & Closures] - The Module Pattern

前言 在本章节中将介绍这本书最重要的程序组织之一,module,module会用到我们之前所介绍的所...

[Day28] Vue3 - 资料绑定

纯 JS 的环境里要改变 DOM 元素,除了要找到他,还要用 setAttribute, textC...

DAY30 MongoDB 使用经验分享 & 完赛

DAY30 MongoDB 使用经验分享 & 完赛 终於来到铁人赛的最後一天了,今天不讲太多...