Amplify + Reactでアプリケーション作成

# 準備
下記コマンドを順番に実行し、Amplify-Reactでの環境を構築する

1.AmplifyCLIをインストール
```
npm install -g @aws-amplify/cli
```
2.Amplifyを設定する
```
amplify configure
Specify the AWS Region
? region:  # Your preferred region
Specify the username of the new IAM user:
? user name:  # User name for Amplify IAM user
Complete the user creation using the AWS console
Enter the access key of the newly created user:
? accessKeyId:  # YOUR_ACCESS_KEY_ID
? secretAccessKey:  # YOUR_SECRET_ACCESS_KEY
This would update/create the AWS Profile in your local machine
? Profile Name:  # (default)

Successfully set up the new user.
```
3.Amplifyプロジェクトを作成する
```
npx create-react-app react-amplified
cd react-amplified
```
4.Amplifyでの初期化
```
amplify init

Enter a name for the project (react-amplified)

# All AWS services you provision for your app are grouped into an "environment"
# A common naming convention is dev, staging, and production
Enter a name for the environment (dev)

# Sometimes the CLI will prompt you to edit a file, it will use this editor to open those files.
Choose your default editor

# Amplify supports JavaScript (Web & React Native), iOS, and Android apps
Choose the type of app that you're building (javascript)

What JavaScript framework are you using (react)

Source directory path (src)

Distribution directory path (build)

Build command (npm run build)

Start command (npm start)

# This is the profile you created with the `amplify configure` command in the introduction step.
Do you want to use an AWS profile
```
5.Amplifyでのパッケージをインストールする
```
npm install aws-amplify @aws-amplify/ui-react@1.x.x
```

# 構成
```
react-amplified
    |   
    +---public
    |      index.html
    |                
    \---src
        |   App.js
        |   aws-exports.js　⇒　自動生成設定ファイル
        |   index.js
        |       
        +---page
        |    　　Index.js
        |    　　Page1.js
        |    　　Page2.js
        |    　　NotFound.js
        |    　　ErrorBoundary.js
```

# 実装

```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

```

```src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Amplify from "aws-amplify";                   
import App from './App';
//予期せぬエラーページ
import ErrorBoundary from './page/ErrorBoundary';
//Amplifyの設定を読み込む
import config from "./aws-exports";
Amplify.configure(config);

ReactDOM.render(<ErrorBoundary><App /></ErrorBoundary>, 
                document.getElementById('root'));

```

```src/App.js
import { withAuthenticator } from 'aws-amplify-react';
import { BrowserRouter, Route } from 'react-router-dom';
import React, { Component } from 'react';
//ページインポート
import Index from './page/Index';
import Page1 from './page/Page1';
import Page2 from './page/Page2';
import NotFound from './page/NotFound';

class App extends Component {
    render() {
        return (
            {/*ルーター宣言*/}
            <BrowserRouter>
                <Route exact path='/' component={Index} />
                <Route exact path='/page1' component={Page1} />
                <Route exact path='/page1' component={Page2} />
                {/*404ページ*/}
                <Route component={NotFound} />
            </BrowserRouter>
        );
    }
}

//Amplifyの高級コンポネント(HoC)をエクスポート
export default withAuthenticator(App);
```

```src/page/Index.js

import React, { Component } from 'react';
export default class Index extends Component {
    
    render() {
        return (
             <div><h2 >Index Page</h2></div>
        );
    }
}
```

```src/page/Page1.js

import React, { Component } from 'react';
export default class Page1 extends Component {
    
    render() {
        return (
            <div><h2 >Page1</h2></div>
        );
    }
}
```

```src/page/Page2.js

import React, { Component } from 'react';
export default class Page2 extends Component {
    
    render() {
        return (
           <div><h2 >Page2</h2></div>
        );
    }
}
```

```src/page/NotFound.js

import React, { Component } from 'react';
export default class NotFound extends Component {
    
    render() {
        return (
               <div><h2 >Error 404: Not Found</h2></div>
        );
    }
}
```

```src/page/ErrorBoundary.js
import React, { Component } from 'react';
export default class ErrorBoundary extends Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }

    static getDerivedStateFromError(error) {
        return { hasError: true };
    }

    componentDidCatch(error, errorInfo) {
        //エラー情報を出力する
        console.error(error, errorInfo);
    }

    render() {
        if (this.state.hasError) {
            // エラー発生するUI
            return (
                <div > <h2 >予期せぬエラーが発生しました。</h2></div>
            );
        }
        return this.props.children;
    }
}
```

# 参考
https://docs.amplify.aws/

https://ja.reactjs.org/

https://reactrouter.com/