React/FastAPI初心者が1日でaxiosで通信する(1週間だけ頑張る Day4of9)

# はじめに
1週間N(E)ETになった社会人の学習記録です。
今日はReactのサンプルを写経し、使い方を覚えます。
前々回作ったFastAPIに対して、CRUDできることを目標にしましたが、できませんでした。

https://qiita.com/tagawa0525/items/8fe2245fc85cdc7979dc

私のHTML/CSSのレベルは、「阿部 寛のホームページ[^1]をかろうじて理解できる。」程度です。
正直、見た目とかどうでもいいので、CSS何それおいしいのって思っています。
ただ、複数カラムに対する絞り込み選択をアクセス並みの便利さにしようとすると、ページ遷移があると厳しそうなので、Ajax（もはや死語？）的な動作が必要なためReactを選んでみました。

私のjavascriptのレベルは、「hello world[^2]」程度です。
取り敢えずReactのチュートリアル[^3]は金曜日（Day0of9）にやってみました。

[^1]: http://abehiroshi.la.coocan.jp/
[^2]: https://github.com/tagawa0525/prac/tree/main/type_script/hello
[^3]: https://ja.reactjs.org/tutorial/tutorial.html

## 開発環境の設定
### vimのアップデート
.tsxのファイルを開いてもsyntaxがつかなかったので、Ubuntu On WSLのvimをversionを8.2に上げた。

https://qiita.com/Fell/items/8619385da8e09a59c787

```shell
sudo su
apt install software-properties-common
apt update
add-apt-repository ppa:jonathonf/vim
apt upgrade
```
sudo suはお行儀が悪いので良い子は使わないこと。

### 開発環境をWSLからWindows側に変更
vimで編集すると、tsxのautoindentがものすごく微妙なので、VS Codeにしよう。

https://github.com/tagawa0525/prac/commit/59f8854f7e27ce9efda141061b0a8f556a8b076a

* ~~volumesのsourceをWindows系のパス(C:\...)に変更~~（結局WSL系のパス（/mnt/c/...）に戻した。）
* 環境変数に「CHOKIDAR_USEPOLLING: 'true'」を追加[^4]（ソースの変更に追随して再Compileをする設定。Ubuntuの場合だと設定しなくてもできる時もあった。）

[^4]: https://qiita.com/galnele/items/b25962e9e287eb9a2146

# 実装
## 参考ページ
とりあえず以下のページが（githubのリンクもあり）わかりやすそうだけど、そもそもReactの使い方は全くわからん。

https://zenn.dev/tatsurom/articles/1bf9bf6f24e14532c58b

https://zenn.dev/tatsurom/articles/0b212d24c80c334d70c9

https://github.com/tatsuro-m/react_rails_api_frontend

## FastAPIとの通信
参考ページを見るとAPIとの通信はReactだけではなく、Axiosというやつを使っているぽい。
とりま「react api　通信」でググるとトップ7/8がAxiosだったので、これにする。

### CORS(Cross-Origin Resource Sharing)[^5]の許可
FastAPIにReactからの通信を許可する設定を追加[^6] [^7]。

```python:main.py
origins = [
    "http://localhost:3000"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```

https://github.com/tagawa0525/prac/commit/8e8d1a6f5fb08975cf95e1326efea322930de0bc

[^5]: http://www.tohoho-web.com/ex/cors.html
[^6]: https://qiita.com/whitphx/items/9278f948520c8d5b7b5a
[^7]: https://fastapi.tiangolo.com/ja/tutorial/cors/

### axiosの設定
サンプルコピペ。


```tsx:App.tsx
  get axios() {
    const axiosBase = require('axios');
    return axiosBase.create({
      baseURL: "http://localhost:8000",
      headers: {
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
      },
      responseType: 'json'
    });
  }
```

### ネットワークのまとめ（かなり怪しい初心者なりの理解）
* Dockerの中だけで完結する場合は、services名(今回はdb, api, web)で通信できる。そのため、api->dbへの接続はFastAPIの「db.py」において、「HOST='db'」としている。
* 一方、Reactの「App.tsx」内の通信はブラウザが行っており、データの流れは後者だと考えられる。そのため、FastAPIの「main.py」において、「origins=["http://localhost:3000"]」とし、axios内のbaseURLは「"http://localhost:8000"」とする。
  * ブラウザ(localhost) ← localhost:3000=web ← api ← db
  * web=localhost:3000 → ブラウザ(localhost) ← localhost:8000=api ← db
* 「App.tsx」内で環境変数をとってくる「process.env.ENV_VALUE」はブラウザ側の環境変数をとってくるみたい。「docker-compose.yml」で環境変数を設定して、main.pyで「os.environ['WEB_URL']」、「App.tsx」で「baseURL: process.env.API_URL」として、環境設定を押し込めたかったけど無理だった。Reactでserver側の環境変数を参照できる方法があったら知りたい。（といいつつ、サーバーの設定を外に出すのは微妙な気がするので、m4マクロみたいに上書きされる仕様になりそうだけども。）


## Index（一覧）
とりま、参考サイトから、一覧表示に必要そうなところだけコピペ。
「@material-ui/data-grid」は一意のidがいるというエラーが出たので、FastAPI側のSchema(UserSelect)にidを追加。

https://github.com/tagawa0525/prac/commit/121d896ceaa1cf47e8544d333aba3bf926d98291#diff-667a3065af0fc8b196dc8fec926405e3948f46afbf71904fe88fc26c9644e60e

とりあえず一覧はできたので、CRUDは明日頑張る。
 
## 所感
ホットリロードの有効化（CHOKIDAR_USEPOLLING=true）とCORSの許可にかなり手間取った。
こういう知ってたら一瞬だけど、知らないと調べようもなくて時間がとられるやつは、学習とはそういうものだと思って楽しむしかない。愚者は経験からしか学べない。
まあ、printfデバッグの方法[^8]すらわからない状況から始めたことを思えば頑張ったと思う。
明日こそはReactからCRUDするぞ。

[^8]: https://qiita.com/mtanabe/items/49a116354c2ad9603942


## 免責事項（言い訳）
上記の技術については初心者なので、あてにしないように!!!