iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🚀

Getting Started with Axios

に公開

Introduction

I wanted to study asynchronous processing, so I introduced Axios on the backend side! (On the frontend, I'm using React.)

Project Overview

I created a project that allows users to add and delete daily reminders. The styling is kept minimal, and I'm using Material-UI for the list section.
reminder

File Structure

├── src/
   ├── components/
           └──Reminder.tsx         	   
   └── index.tsx
   └──App.tsx
   └──db.json

Root App.tsx (Full Code)

I regret that this App file exceeded 100 lines and should have been broken down into more components...
For now, I'll show you the whole thing.

App.tsx
import './App.css';
import React, { useState, useEffect } from 'react';
import Axios from 'axios';
import {
  makeStyles,
  Table,
  TableBody,
  TableContainer,
  Theme,
  Typography,
} from '@material-ui/core';
import useHead from './components/Reminder';

const useStyles = makeStyles((theme: Theme) => ({
  table: {
    marginTop: theme.spacing(3),
    '& thead th': {
      fontWeight: '600',
      color: theme.palette.primary.main,
    },
  },
}));

type FormData = {
  id: number;
  reminder: string;
  time: string;
};

export type HeadCells = {
  id: number;
  label: string;
}[];

const headCells: HeadCells = [
  { id: 0, label: 'id' },
  { id: 1, label: '予定' },
  { id: 2, label: '時間帯' },
];
const data: FormData = {
  id: 0,
  reminder: '',
  time: '',
};

const App = () => {
  const classes = useStyles();

  const [reminder, setReminders] = useState<FormData[]>([]);
  const [formData, setFormData] = useState<FormData>(data);

  const axios = Axios.create({ baseURL: 'http://localhost:3000' });

  const noReminder = !reminder || (reminder && reminder.length === 0);

  const getReminders = async () => {
    const response = await axios
      .get<FormData[]>('/reminders')
      .catch((err) => console.log('err:', err));

    if (response && response.data) setReminders(response.data);
  };
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData({ ...formData, [name]: value });
  };
  const addReminder = async () => {
    const response = await axios
      .post<FormData>('/reminders', formData)
      .catch((err) => console.log('err:', err));

    if (response) getReminders();
  };
  const deleteReminder = async (id: number) => {
    const response = await axios
      .delete(`/reminders/${id}`)
      .catch((err) => console.log('Error deleting:', err));
    if (response) await getReminders();
  };
  const { CardHead, Reminder } = useHead(headCells);

  useEffect(() => {
    getReminders();
  }, []);
  return (
    <>
      <Typography variant="h4" align="center">
        今日の予定
      </Typography>

      {noReminder && <h2>No Reminders found!</h2>}
      <TableContainer>
        <Table className={classes.table}>
          <CardHead />
          <TableBody>
            {!noReminder &&
              reminder.map((reminder, id) => (
                <Reminder key={id} {...reminder} onDelete={deleteReminder} />
              ))}
          </TableBody>
        </Table>
      </TableContainer>

      <br />
      <h3>予定の追加</h3>
      <form onSubmit={addReminder}>
        <label htmlFor="id">Id</label>
        <input name="id" placeholder="Id" onChange={handleChange} />
        <label htmlFor="reminder">予定</label>
        <input name="reminder" placeholder="予定" onChange={handleChange} />
        <label htmlFor="time">時間帯</label>
        <input name="time" placeholder="Am or Pm" onChange={handleChange} />
        <button type="submit">追加</button>
      </form>
    </>
  );
};

export default App;

Code Details

Let's look at the code in parts.
First, an instance is created using the create method.

createメソッド
const axios = Axios.create({ baseURL: 'http://localhost:3000' });

The data (id, reminder, time) is stored in db.json. I learned how to set up JSON Server from this article: Mastering JSON Server. The get method and delete method of Axios handle the add and delete operations on this JSON file. The angle brackets specify TypeScript's generic types.

get,deleteメソッド
const getReminders = async () => {
    const response = await axios
      .get<FormData[]>('/reminders')
      .catch((err) => console.log('err:', err));

    if (response && response.data) setReminders(response.data);
  };
  
  const deleteReminder = async (id: number) => {
    const response = await axios
      .delete(`/reminders/${id}`)
      .catch((err) => console.log('Error deleting:', err));
    if (response) await getReminders();
  };

The getReminders function, which uses the get method, is executed after the render result is reflected on the screen, using useEffect. The second argument of useEffect specifies setReminders, which is the only dependency variable.

useEffect(() => {
  getReminders();
}, [setReminders]);

Next, we use the post method to register data. The second argument passes the data to be registered.

const addReminder = async () => {
    const response = await axios
      .post<FormData>('/reminders', formData)
      .catch((err) => console.log('err:', err));

    if (response) getReminders();
  };

This asynchronous function (addReminder) is assigned to the onSubmit attribute of the form tag, and the handleChange function is assigned to the onChange attribute of the input tag to handle changes in individual data (id, reminder, time).

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData({ ...formData, [name]: value });
  };

//JSX.Element
<form onSubmit={addReminder}>
​ <label htmlFor="id">Id</label>
​ <input name="id" placeholder="Id" onChange={handleChange} />
  <label htmlFor="reminder">予定</label>
  <input name="reminder" placeholder="予定" onChange={handleChange} />
  <label htmlFor="time">時間帯</label>
  <input name="time" placeholder="Am or Pm" onChange={handleChange} />
  <button type="submit">追加</button>
</form>
    </>

The creation of this handleChange function was discussed in a previous article! Things I stumbled upon while creating forms

Also, the useReminder function is imported from a separate file (Reminder.tsx).

App.tsxの一部
import useReminder from './components/Reminder';

const { CardHead, Reminder } = useReminder(headCells);

Below is the entire Reminder.tsx file.

Reminder.tsx
import { Grid, TableCell, TableHead, TableRow } from '@material-ui/core';
import React from 'react';
import DeleteForeverIcon from '@material-ui/icons/DeleteForever';
import { HeadCells } from '../App';

interface Props {
  id: number;
  reminder: string;
  time: string;
  onDelete: (id: number) => any;
}

const useReminder = (headCells: HeadCells) => {
  const CardHead: React.FC = () => {
    return (
      <TableHead>
        {headCells.map(({ id, label }) => (
          <TableCell key={id} align="center">
            {label}
          </TableCell>
        ))}
      </TableHead>
    );
  };

  const Reminder: React.FC<Props> = ({ id, reminder, time, onDelete }) => {
    return (
      <>
        <TableRow key={id}>
          <TableCell align="center">{id}</TableCell>
          <TableCell align="center">{reminder}</TableCell>
          <TableCell align="center">{time}</TableCell>
          <Grid className="reminder-remove" onClick={() => onDelete(id)}>
            <DeleteForeverIcon />
          </Grid>
        </TableRow>
      </>
    );
  };

  return { CardHead, Reminder };
};

export default useReminder;

The creation of a function (useReminder) that wraps such child components as a single function was discussed in the previous article, so please take a look! I want to pass Props more smartly!

That's all for the code details. Thank you for reading this far!!

Discussion