AmplifyとReactでCognito認証ページを作る(その3)

今回、4階部分(React/JSX)の前半となる。前回までの作業で、Amplifyのバックエンドと、Authenticatorの初期設定は完了したため、新規ユーザー登録、ログイン、ログイン後にHelloWorld的な文字列を出す、は可能となった。あとはReactで独自画面を実装していく。

実現したいことのイメージ(6階建ての4階部分)

今回は基礎的な実装方法を押さえておき、Authenticatorの実装は次回とする。

React(JSX)を使って、ログイン後のマイページトップ画面とユーザー情報変更画面を作っていく。

実現したい画面遷移

参考まで、前回作った初期状態の画面を以下にアップロードしておく。
http://react.twinkangaroos.com.s3-website-ap-northeast-1.amazonaws.com/

4階:React/JSXで画面を作る<基礎編>

Reactで実現したいこと<基礎編>

逆引き的に考え、以下の3つを実現したい。あまりにも基本的すぎて、React本では、Reactの専門知識(技術者としては興味深いと言えなくもないが)の説明に忙殺されておざなりになることが多いが、最初に教えて欲しい部分である。

  1. ページを新しく作る
  2. URLにページを紐つける
  3. ページをリンクする

例えると、英語の文法を完璧にマスターしてから洋書を読むよりも、まずは日本語で知っている小説の洋書バージョンを読んで生きた英文に触れてから文法を確認する方が(個人的には)進めやすい。

1.ページを新しく作る

まずは、Reactがどういった仕組みで動いているのか確認しておく。前回のApp.js(Authenticator)のソースを見てみる。

■/src/App.js
import { Amplify } from 'aws-amplify';

import { Authenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

import awsExports from './aws-exports';
Amplify.configure(awsExports);

function App() {
  return (
    <Authenticator>
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
  );
}

export default App;

function App() を以下のように変更してみる。そうすると、同じようにログイン画面が表示される(ただしログイン後の画面は真っ白になる)。

function App() {
  return (
    <Authenticator />
  );
}

つまり、Authenticatorというコンポーネントを呼び出し、そこでHTML要素がreturnされるのでそれを出力している。考え方としては、例えば以下のBlankPageコンポーネントの呼び出しと同じ意味である。

■/src/App.js
import BlankPage from "./pages/BlankPage";

function App() {
  return (
    <BlankPage />
  );
}
export default App;

BlankPage.js(BlankPageコンポーネント)は以下のように作っておく。

■/src/pages/BlankPage.js
const BlankPage = () => {
  return (
    <div>
      空っぽのページです。
    </div>
  );
}
export default BlankPage;

そうすると以下のように表示される。

空っぽのページ

ちなみに、Authenticatorコンポーネントが具体的にどのような仕組みで動いているのか知りたくなって調べようとしたが、残念ながら難しい。なぜなら、(以下のディレクトリに格納されているようだが)ソース圧縮されていることもあり解読はほぼ不可能である。

/node_modules/@aws-amplify/ui-react/dist/esm/components/Authenticator
Authenticator.mjs

そのため、以下のリファレンスをとっかかりに進めていくことになる。

■Authenticator | Amplify UI for React
https://ui.docs.amplify.aws/react/connected-components/authenticator

中身がブラックボックスでありそれらのライブラリを信じるしかなく、実運用する場合は怖いところではある。なぜなら、万が一、そのライブラリ内でバグが発生したとした場合、対応に高度な対応スキルが求められるためである。そのリスクを踏まえた上で(腹を決めた上で)導入する必要がある。このあたりは次回、簡単に解説する。

2.URLにページを紐つける

URLパスに紐づくページ設定を行う。概念としては以下のイメージ。

URLパスに紐づくページのイメージ

事前に以下を実行してReact Routerをインストールしておく。

npm install react-router-dom

以下のApp.jsの一部ソースをLoginPage.jsに移動する。

■/src/App.js
import { Amplify } from 'aws-amplify';

import { Authenticator } from '@aws-amplify/ui-react'; ←移動
import '@aws-amplify/ui-react/styles.css';

import awsExports from './aws-exports';
Amplify.configure(awsExports);

function App() {
  return (
    ↓移動
    <Authenticator>
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
    ↑移動
  );
}

export default App;

LoginPage.jsは以下の通り。

■/src/pages/LoginPage.js
import { Authenticator } from '@aws-amplify/ui-react';

const LoginPage = () => {
    return (
        <Authenticator>
        {({ signOut, user }) => (
          <main>
            <h1>Hello {user.username}</h1>
            <button onClick={signOut}>Sign out</button>
          </main>
        )}
        </Authenticator>
      );
}

export default LoginPage;

App.jsは以下のようにソースを追加する。

■/src/App.js
import { Amplify } from 'aws-amplify';
import '@aws-amplify/ui-react/styles.css';

↓追加
import { Route, Routes, BrowserRouter } from "react-router-dom";
import BlankPage from "./pages/BlankPage";
import LoginPage from "./pages/LoginPage";
↑追加

import awsExports from './aws-exports';
Amplify.configure(awsExports);

function App() {
  return (
    ↓追加
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<LoginPage />} />
        <Route path="/blank" element={<BlankPage />} />
      </Routes>
    </BrowserRouter>
    ↑追加
  );
}

export default App;

これで、”/”にアクセスするとログイン画面、”/blank”にアクセスするとブランクページに遷移できる。

3.ページをリンクする

次に、ログイン後の画面で試しにブランクページへのリンクをつける。LoginPage.jsに以下を追加する。

■/src/pages/LoginPage.js
import { Authenticator } from '@aws-amplify/ui-react';
import { Link } from "react-router-dom"; ←追加

const LoginPage = () => {
    return (
        <Authenticator>
        {({ signOut, user }) => (
          <main>
            <h1>Hello {user.username}</h1>
            <button onClick={signOut}>Sign out</button>
            <p><Link to="/blank">ブランクページへ</Link></p> ←追加
          </main>
        )}
        </Authenticator>
      );
}

export default LoginPage;

ログイン後、以下のように表示される。

ログイン後の画面

次回は、Authenticatoを使った簡単なカスタマイズを行う。

(余談)最初に参考にして挫折した本

当初、以下のReact本を読んでいたのだが、なかなか自分で動くものが作れそうな気配がなかった(私の知識不足かもしれませんが・・)。

上記に比べて(個人的に)理解しやすかった以下のKindle本が理解しやすかった。

■はじめてつくるReactアプリ (React入門シリーズ) | 三好アキ | 一般・入門書 | Kindleストア | Amazon
https://www.amazon.co.jp/gp/product/B08XWMVX76

上記の後に以下を読むとさらに理解が深まった。

■はじめてさわるReact & JavaScript (React入門シリーズ) | 三好アキ | 一般・入門書 | Kindleストア | Amazon
https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%95%E3%82%8F%E3%82%8BReact-JavaScript-mod728-ebook/dp/B09693ZJCV/

言語の仕様から入るのではなく、まずは動いているものを作った後に理解するスタイルが自分には合っているように思う。