React アプリに Amazon S3 上の CSV データをテーブルで表示する

こんにちは、広野です。

本記事は、以下の続編記事です。

今回は前回記事で紹介した構成の亜種で、読み込みたいファイルのフォーマットが JSON ではなく CSV だった、というケースに対応したパターンです。

基本的な構成は同じなので構築する環境については前回記事をお読み頂き、前回から変更している箇所のみ解説とさせて下さい。
変更箇所は React アプリコードのみとなります。React アプリ側で CSV から JSON にデータ変換をかけて画面表示させる処理をさせています。そのための React モジュールとして react-papaparse を使用します。

react-papaparse
The fastest in-browser CSV (or delimited text) parser for React.

前回記事から変わった環境

  • 今回は Amazon S3 に配置するファイルが CSV ファイルに変わっただけです。

  • testdata.csv
menu,id,neta
menu1,1,いか
menu1,2,たこ
menu2,1,海鮮丼

前回記事から変わった React コード

react-papaparse の、リモート CSV ファイルを読み込むモジュールを使用します。以下の公式サンプルコードを参考にして書きます。

react-papaparse
The fastest in-browser CSV (or delimited text) parser for React.
  • App.js
import React, {useState, useEffect} from 'react';
import { usePapaParse } from 'react-papaparse';
import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack';
import { styled } from '@mui/material/styles';
import Paper from '@mui/material/Paper';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell, { tableCellClasses } from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import { blue } from '@mui/material/colors';

const App = () => {
  //テーブルデザイン設定
  const StyledTableCell = styled(TableCell)(({ theme }) => ({
    [`&.${tableCellClasses.head}`]: {
      backgroundColor: blue[900],
      color: theme.palette.common.white,
      fontSize: 14,
      fontFamily: "inherit"
    },
    [`&.${tableCellClasses.body}`]: {
      fontSize: 14,
      fontFamily: "inherit"
    }
  }));
  const StyledTableRow = styled(TableRow)(({ theme }) => ({
    '&:nth-of-type(odd)': {
      backgroundColor: theme.palette.action.hover
    }
  }));
  
  //state初期化
  const [jsonData, setJsonData] = useState([]);
  
  //データ取得関数
  const { readRemoteFile } = usePapaParse();
  const getCsvData = () => {
    readRemoteFile("https://xxxxxxxxxxxxxx.cloudfront.net/data/testdata.csv", {
      complete: (results) => {
        setJsonData(results.data);
      },
      header: true,
      skipEmptyLines: true
    });
  };

  //画面表示時にデータ取得
  useEffect(() => {
    getCsvData();
  }, []);
  
  return (
    <div id="page-wrapper">
      {/* Main */}
      <div id="main">
        <div className="container">
          <div className="row main-row">
            <div className="col-12 col-12-medium col-12-small">
              <section>
                <Grid container spacing={{ xs: 2, sm: 2, md: 2 }}>
                  <Grid item xs={12} sm={12} md={6}>
                    <Stack direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
                      <TableContainer component={Paper}>
                        <Table size="small" aria-label="testdata">
                          <TableHead>
                            <TableRow>
                              <StyledTableCell align="center">メニュー</StyledTableCell>
                              <StyledTableCell align="center">ID</StyledTableCell>
                              <StyledTableCell align="center">ネタ</StyledTableCell>
                            </TableRow>
                          </TableHead>
                          <TableBody>
                            {jsonData.map((row) => (
                              <StyledTableRow>
                                <StyledTableCell align="center">{row.menu}</StyledTableCell>
                                <StyledTableCell align="center">{row.id}</StyledTableCell>
                                <StyledTableCell align="center">{row.neta}</StyledTableCell>
                              </StyledTableRow>
                            ))}
                          </TableBody>
                        </Table>
                      </TableContainer>
                    </Stack>
                  </Grid>
                </Grid>
              </section>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default App;
  • 画面に描画する部分、return ( ) 内は全く変更していません。
  • CSV データを取得しにいくためのモジュールに react-papaparse を使用するため、axios が削除されています。
  • データ取得関数の名前を getCsvData に変更しています。
  • getCsvData の中では react-papaparse が指定の URL にある CSV ファイルにアクセスします。CSV ファイルの中のデータを読み込み、JSON データに変換したものが results.data に格納されます。
  • results.data を console.log で表示したものが以下です。期待した JSON データになっています。

  • results.data をステート jsonData に格納すると、テーブルが描画されます。元データは CSV ですが、前回記事と全く同じテーブルがめでたく表示されました。

まとめ

いかがでしたでしょうか?

実運用では JSON よりも CSV の方が扱いやすいので、こちらの方が実用的なアプリコードになると思います。

本記事が皆様のお役に立てれば幸いです。

著者について
広野 祐司

AWSサーバーレスアーキテクチャを駆使して社内クラウド人材育成アプリや教育コンテンツをつくっています。ReactでSPAを書き始めたら、快適すぎて他の開発言語には戻れなくなりました。AWSサーバーレスやReactの仲間を増やしたいです。
取得資格:AWS認定は7つ、ITサービスマネージャ、ITIL v3 Expert、等
2020, 2021 APN AWS Top Engineers 受賞
2022 AWS Partner Ambassador 受賞
好きなAWSサービス:AWS Amplify / Amazon Cognito / AWS Step Functions / AWS CloudFormation

広野 祐司をフォローする
クラウドに強いによるエンジニアブログです。
SCSKは専門性と豊富な実績を活かしたクラウドサービス USiZE(ユーサイズ)を提供しています。
USiZEサービスサイトでは、お客様のDX推進をワンストップで支援するサービスの詳細や導入事例を紹介しています。
AWSサーバレスアーキテクチャその他技術ナレッジ
TechHarmony
タイトルとURLをコピーしました