七転八転

よしなしごとを。

フロントエンド頑張る編(React)

前置き

この記事は平穏な生活を送りたいぴょこりんクラスタ Advent Calendar 2022 - Adventarのために書かれたものです。

本題

やったこと

darumap.hatenablog.com
去年やっていた続きをやりました。

去年はMySQLで作ったデータベースから、データを引っこ抜いて返すバックエンド(express)を作りました。ということで、今年はようやくフロントエンド側に着手します。一応Reactで頑張る方向で。

+--------+--------------+------+-----+---------+----------------+
| Field  | Type         | Null | Key | Default | Extra          |
+--------+--------------+------+-----+---------+----------------+
| id     | int(11)      | NO   | PRI | NULL    | auto_increment |
| food   | varchar(255) | YES  |     | NULL    |                |
| kind   | varchar(255) | YES  |     | NULL    |                |
| amount | int(11)      | YES  |     | NULL    |                |
+--------+--------------+------+-----+---------+----------------+

+----+-------+------+--------+
| id | food  | kind | amount |
+----+-------+------+--------+
|  1 | beef  | meat |      2 |
|  2 | pork  | meat |      3 |
|  3 | sushi | fish |      3 |
+----+-------+------+--------+

バックエンド側でAPI叩くと上記のデータがMySQLからかえってくるようにして、kindに応じてそれぞれリストを表示するようにします。
http://localhost:3001/api/foodsを叩くと、返ってくるようにしています。
こんな感じに表示されるものを作りました。

つくったもの

ソースコードはこちら。
App.js

import './App.css';
import FoodList from './components/FoodList';
import React from "react";
import {useState, useEffect} from 'react';
import axios from 'axios';

const db_url = "http://localhost:3001/api/foods";

function App() {
  const [data, setData] = useState(0);

  useEffect(() =>{
    axios.get(db_url).then((response) => {
      setData(response.data);
    })
  },[]);
  console.log(data);

  if(!data) return null;

  const data_m = data.filter( (datum) => {
    return datum.kind === 'meat';
  });

  const data_f = data.filter( (datum) => {
    return datum.kind === 'fish';
  });

  return (
    <div className="App">
      <FoodList title='meat' data={data_m}/>
      <FoodList title='fish' data={data_f}/>
    </div>
  );
}

export default App;

component/FoodList.jsx

import * as React from 'react';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';

export default function FoodList(props) {
  return (
    <div>
      <h1>{props.title}</h1>
      <TableContainer component={Paper}  sx={{
        display: 'flex',
        maxWidth: 800,
        m: 'auto'
        }} >
        <Table aria-label="simple table">
          <TableHead>
            <TableRow>
              <TableCell>Food</TableCell>
              <TableCell align="right">amount</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {props.data.map((row) => (
              <TableRow
                key={row.food}
                sx={{ '&:last-child td, &:last-child th': { border: 0 }}}
              >
                <TableCell component="th" scope="row">
                  {row.food}
                </TableCell>
                <TableCell align="right">{row.amount}</TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </div>
  );
}
感想

何かをやろうとするとcss, js, Reactの各レイヤの知識が混然と求められるので正直大変な印象。それぞれ頑張らんと…。