React18 × TypeScript × RestApiの実践

# Ⅰ. 技術要素
・　react@18.1.0
・　typescript@4.7.3
・　axios@0.27.2
・　styled-components@5.3.5
・　Springboot
・　OpenApi（Swagger）
・　MyBaits
・　MySQL


# Ⅱ. 事前準備
### 1. React + Typescrpitをインストール
```
npx create-react-app samplets --template typescript
```
### 2. styled-componentsをインストール
```
yarn add styled-components
yarn add --dev @types/styled-components
```
### 3. axiosをインストール
```
npm install axios
```

# Ⅲ. 主な機能

### 1. 工程のエンティティ (MySQL)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697792/c942c72e-042b-c2db-2020-bc5d6669aaac.png)

### 2. バックエンド機能 (Springboot × OpenApi  × Swagger  × MyBaits)
・　工程のエンティティのCRUD


### 3. フロントエンド機能 (React × Typescrpit × axios)
・　工程一覧が表示できる
・　工程が登録できる
・　工程が削除できる

# Ⅳ. 実装
### 1. バックエンド部分
#### ①. イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697792/72e941e5-607f-623c-0692-c70706e424c4.png)

#### ②. ソースコード
https://github.com/hansei860303/sample1/

※具体的な説明を割愛する

### 2. フロントエンド部分

#### ①. 画面イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697792/f37d8c15-ee66-272f-d976-702aa276cbcc.png)

#### ②. ソースコード
```typescript:App.tsx
import styled from "styled-components"
import axios from "axios";
import { useEffect, useState } from "react";

/** axios Start */ 

// 工程一覧取得
async function getPhases(url:string): Promise<phase[]> {
  try {
    
    const response = await axios.get<phase[]>(url);
    console.log(response);
    return response.data;
  } catch (error) {
    console.error(error);
    return [];
  }
}

// 工程新規
async function putPhases(url:string,phase:phase): Promise<any> {

  try {
    const response = await axios.put(url, phase);
    console.log(response);
    return true;
  } catch (error) {
    console.error(error);
    return false;
  }
}

// 工程削除
async function deletePhases(url:string,id:number): Promise<any> {

  try {
    const response = await axios.delete(url + id);
    console.log(response);
    return true;
  } catch (error) {
    console.error(error);
    return false;
  }
}

/** axios End */ 


// メインレコード
type phase = {
  id: number;
  phase: string;
  sort:number
}

function App() {
  // タイトル
  let title:string = "工程一覧";

  // 工程一覧
  const [phases, setPhases] = useState<phase[]>([]);

  // 工程名
  const [phase, setPhase] = useState("");

  // 工程順
  const [sort, setSort] = useState(0);

  // 初期表示
  useEffect(() => {

    reflashPhases();
  
  }, []);

  // 工程名入力
  const doChangePhase = (event:any)=>{
    setPhase(event.target.value)
  }

  // 工程順入力
  const doChangeSort = (event:any)=>{
    setSort(event.target.value)
  }

  // 新規ボタン
  async function doSubmit () {

    if(phase !== "" && sort > 0) {
      let newPhase : phase = {id:0,phase:phase,sort:sort};
      const url1= "http://localhost:9003/api/phases/save";
      await putPhases(url1,newPhase);
      await reflashPhases();
    }
}

  // 削除ボタン
  async function doDelete (id:number) {
    const url = "http://localhost:9003/api/phases/delete/";
    await deletePhases(url,id);
    await reflashPhases();
}

  // 再読み込み
  async function reflashPhases() {
    
    const url = "http://localhost:9003/api/phases/findAll";
    const phases = await getPhases(url);
    setPhases(phases);
  
  }


  // JSX
  return(
    <div>
      <h1>{title}</h1>
      <form onSubmit={doSubmit}>
          <p>{"名　称："}<input type="text" onChange={doChangePhase}/></p>
          <p>{"順　番："}<input type="number" onChange={doChangeSort}/>&nbsp;&nbsp;
            <input type="submit" value="追加" />
          </p>
      </form>
      <SContainer>
        <ol>{phases.map((phase: phase) => (
          <SMemoWrapper>
            <li key={phase.id}>{phase.phase}<SButton onClick={() => doDelete(phase.id)}>削除</SButton>
            </li>
          </SMemoWrapper>
          ))}
        </ol>
    </SContainer>
    </div>
  );

}

const SButton = styled.button`
margin-left:16px;
`;


const SContainer = styled.div`
border:solid 1px #ccc;
`;

const SMemoWrapper = styled.div`
display:flex;
align-items:center;
`;

export default App;
```

#### ③. 注意点
複数のaxiosメソッドを順番に使う場合、非同期処理のため、並列処理することが必要

#### ④. 課題
コンポーネントの作り方


# Ⅴ. まとめ
### 1. なぜReactを使うのか？
JavaScriptの主な問題：
・　コード量が多い
・　管理が難しい
・　複数人での共同開発がしにくい
これらの問題を解決するため、React、Vue、Anguarなど、JavaScriptフレームワークが出ていった

### 2. なぜTypescrpitを使うのか？
・　JavaScriptの「型」をより意識することで、ソースを規範化にする
・　仕様に柔軟に対応できる

### 3. 基本的なコンポネント化方式

画面ウェジット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697792/fbe66b8a-e677-7907-e1a3-f80c70b875df.png)

コンポネント化方式
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697792/5d691e58-432a-8323-74d6-3ed986cf38e3.png)

# Ⅵ. 参考文献
・　モダンJavaScriptの基本から始める　React実践の教科書 | じゃけぇ（岡田 拓巳）
・　React.js＆Next.js超入門 第2版 | 掌田津耶乃
・　はじめてつくるReactアプリ | 三好アキ