Reactの勉強①　RestAPIと一覧表示

**今回の狙い**
裏方となるバックエンド処理（サーバ処理）は、RedmineのRestAPIを利用します。
表面となるフロント処理にREACT（MUI）を利用してみます。

前回の記事の環境を、フロント処理のベースに利用します。

https://qiita.com/MasahiroShouya/items/8ae4ffa73a6b39681ba6

以下のRedmineのRestAPIを、バックエンド処理に利用します。

https://qiita.com/MasahiroShouya/items/aaf5d51b05846f196a0f

**Redmine（RestAPI）**
初回のユーザ／パスワードは、adminになってます。
今回、ユーザ一覧のAPIを使うので、何件かユーザ登録を行いましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3878922/25ee0c62-3dc5-4b77-98dc-e9e745ab1cd1.png)
設定の機能から、RestAPIを有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3878922/321f14d6-7fd8-4cb6-ba18-d692e0f4614d.png)
個人設定からAPI情報を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3878922/918b78d9-37d6-4735-8c2c-8a932f3bb09a.png)
ブラウザから、「 http://localhost:3001/users.json?key=※上記のAPIキー 」へアクセスし、JSONが表示されることを確認しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3878922/7321b43c-4383-48ce-900f-801cfa27877a.png)
以上で、バックエンド処理（サーバ処理）の準備は完了です。

実際のところは、この部分が、WindowsであればC#でAPIを構築したりする部分です。
バックエンド処理（サーバ処理）は、外からの受信PORTを解放せずに、外部からアクセスさせないようにして、セキュリティに気を付けて環境構築する等の最低限の対応は実施しましょう。
（※ REACTからのみ、アクセス可能であれば良いのです）

**フロント処理（React）MUI**
勉強環境は、概ね、前回のリンクで完了してます。
プログラムを差し替えて、MUIが動作することを確認してみましょう。
Reactのソースコードは、Reactホームの「src」フォルダの下です。
下記、「index.js」と「WebApi.js」の２つだけ
```diff_javascript:src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './WebApi';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
```
```diff_javascript:src/WebApi.js
import { useEffect, useState } from 'react';
import { Table, TableContainer, TableHead, TableBody, TableRow, TableCell, Paper, Typography } from '@mui/material';
const fetchRedmine = async () => {
  const res = await fetch(`http://localhost:3001/users.json?key=※上記のAPIキー`);
  if (res.ok) { return res.json(); }
  throw new Error(res.statusText);
};
export default function WebApi({ id }) {
  const [data, setData] = useState(null);
  const [isLoading, setLoading] = useState(true);
  const [error, setError] = useState('');
  useEffect(() => {
    setLoading(true);
    fetchRedmine()
      .then(result => setData(result))
      .catch(err => setError(err.message))
      .finally(() => setLoading(false));
  }, []);
  if (isLoading) {
    return <p>Loading...</p>;
  }
  if (error) {
    return <p>Error: {error}</p>;
  }
  return (
    <div>
      <Typography variant="h6" gutterBottom>
        ユーザー一覧
      </Typography>
      <TableContainer component={Paper}>
        <Table sx={{ minWidth: 650 }} aria-label="user table">
          <TableHead>
            <TableRow>
              <TableCell>ID</TableCell>
              <TableCell>ログイン</TableCell>
              <TableCell align="center">管理者</TableCell>
              <TableCell>名</TableCell>
              <TableCell>姓</TableCell>
              <TableCell>メール</TableCell>
              <TableCell>作成日</TableCell>
              <TableCell>最終ログイン</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {data?.users?.map((user) => (
              <TableRow
                key={user.id}
                sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
              >
                <TableCell component="th" scope="row">
                  {user.id}
                </TableCell>
                <TableCell>{user.login}</TableCell>
                <TableCell align="center">{user.admin ? 'はい' : 'いいえ'}</TableCell>
                <TableCell>{user.firstname}</TableCell>
                <TableCell>{user.lastname}</TableCell>
                <TableCell>{user.mail}</TableCell>
                <TableCell>{user.created_on}</TableCell>
                <TableCell>{user.last_login_on || 'なし'}</TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </div>
  );
}
```

**実行して確認してみましょう**
Reactの開発環境を起動します。
※事前にRedmineが起動している事を確認しておきましょう。
cd reactホーム
npm start
ブラウザに以下の画面が表示されれば完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3878922/fae98434-d831-4426-90c0-a07d7e4ad762.png)

IISにビルドしましょう。
npm run build
IISのポートからアクセスしてみましょう。
「Error: Failed to fetch」が表示されていませんか？
これは、Redmine側が、CORSエラーを起こしているはずです。
Redmineの「config.ru」の以下の行に、IISのポートも追記して、Redmineを再起動してからテストしてみましょう。
＞ origins 'http://localhost:3000', 'http://localhost:82'
正常に、IISポートでも表示されるはずです。

お疲れさまでした～。