windows10
react@17.0.1
aws-amplify@3.3.14
プロジェクトを作る
npxで作成する (公式)
npx create-react-app sukina-project-name
起動
cd sukina-project-name
npm start
画面(部品)の作成
1部品で1画面を作ることも可能。しかし、小さく作って組み合わせる方が再利用性が高くてスマート
作成した直後のプロジェクトの中にあるApp.jsのように、描画する画面を返す関数を定義するか、
// functionで描く
export default function Welcome() {
return <h1>Hello World</h1>;
}
クラスを作ってrender関数で返す
import React from "react";
//class.renderで描く
export default class Welcome extends React.Component {
render() {
return <h1>Hello World</h1>;
}
}
export defaultは下でもよい
class Welcome extends React.Component {
render() {
return <h1>Hello World</h1>;
}
}
export default Welcome;
配列の中身を書きだしたい
const values = [ 1, 2, 3 ]
return (
{values.map( (v) => <div>{v}</div> ) }
//{for(let v in values){ <div>{v}</div> }} 式は書けないのでこれは無理
)
や
const values = [ 1, 2, 3 ]
let items = []
for(let v in values){ items.push( <div> {v} </div>) }
return (
{items}
)
画面遷移したい
React Routerを使う。(公式)
React Routerのインストール(公式)
npm install react-route-dom
ここでは例として、/todo というURLを指定した時に表示したいページを作っている
src直下にTodo.jsを作成
// /todoでアクセスすると描画する内容
import React,{ Component } from 'react'
export default class Todo extends Component {
render(){
return <div> hello! </div>;
}
}
BrowserRouter、Suspense、Switch、Routeコンポーネントを使って、表示先を選択する
インポート部分
// React.lazyとReact.Suspenseをインポート
import React , {Suspense,lazy} from 'react';
import './App.css';
// React Routerからインポート
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
// 前で作ったTodoクラスを取り込み
const Todo = lazy(() => import('./Todo'));
Todo.jsをApp.jsにインポート
描画処理
function App() {
return (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route path="/todo" component={Todo} />
<Route path="/">
<h1>root</h1>
</Route>
</Switch>
</Suspense>
</Router>
);
}
export default App;
Router、Switch、Routeタグを使ってurlに対応するコンポーネントを切り替える
<Suspense>は、読みこみ中の間に表示する、ちょっと待ってね的表示。ここではLoading...と表示される
lazyで読み込んだコンポーネントを表示する場合は、<Suspense>の中で呼び出さないと、
A React component suspended while rendering, but no fallback UI was specified.といわれる。
Routeの書き方は以下のどちらも同じ意味
<Route path="/todo" component={Todo} />
<Route path="/todo">
<Todo />
</Route>
ボタンで画面遷移したい
Linkコンポーネントでボタンを囲むと、ボタンを押したとき画面遷移する
import { Link } from 'react-router-dom'
<Link to="/todo">
<button>Login</button>
</Link>
というか、buttonに限らずlabelやspanなどでも画面遷移する
UIライブラリ
いろいろあるので気に入ったものを使えばよいが、
困ったら標準的な部類ということでmaterial-uiが良さそう
フックとは
例えば、classを使って状態を保存する場合はstate機能を使用する。
state等のreactが持つ機能を、クラスでは無くて関数で使うために(画面はclassでも関数でも作れるから用意された関数をフックという。
state機能を使うためのフックをステートフックという。
使用上の注意あり(公式)。
・常にトップレベルで使う事。つまりif,forといった{}の中で使ってはいけない。
・reactコンポーネントの中だけで使用する。純粋なjavascript関数の中で使用してはいけない。
破ると動かない?予期しない動作となる?
ユーザー認証、ユーザー登録をしたい(AWS Cognito , AWS Amplify)
サインアップ、サインインなどをしたい時。
自分でゴリゴリ実装するのではなくAWS Cognitoを使用するケース。
reactからAWS Cognitoを使用するには、AWS Amplifyを利用するのが早い。
AWS Amplifyのインストールと初期の設定 (公式)
amplifyをインストール
初期設定の為、以下のコマンドをプロジェクトのルートで実行
amplify init
AWS Cognitoにユーザープール等を作る時、Amplifyを使って作る場合はコマンドから作成できる。(公式)
手動でユーザープール等AWSリソースを作る場合はこれらのコマンドは不要
amplify add auth
amplify push
amplify pushによりユーザープール等が作成される。
またamplify pushが完了すると、src直下に、作成したAWSリソースにアクセスするための情報が入ったaws-export.jsが作成される。↓
//生成されたaws-exports.js *****にはユーザープール等の情報が設定されている
/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.
const awsmobile = {
"aws_project_region": "*****",
"aws_cognito_identity_pool_id": "*****",
"aws_cognito_region": "*****",
"aws_user_pools_id": "*****",
"aws_user_pools_web_client_id": "*****",
"oauth": {}
};
export default awsmobile;
手動で作った既存のAWS Cognitoリソースを使いたい場合は、
このaws-exports.jsの内容を、使いたい既存リソースのIDに変更する。(公式)
aws_cognito_identity_pool_idが分かりにくかったので確認方法をメモる
IDプールのIDに書いてある文字列全部
Unable to verify secret hash for clientとか言われる時は、
アプリクライアントを追加する時に、「クライアントシークレットを生成」にチェックを入れている可能性がある。
この場合、「クライアントシークレットを生成」をチェックしない様にしてアプリクライアントを再登録する。(IDが新しくなるので変更する)
AWS Cognito Identity NotAuthorizedException
非ログイン時、ページにダイレクトアクセスされたら認証に飛ばしたい
AmplifyAuthenticatorコンポーネントを使用する。(公式)
App.jsの描画処理で、<AmplifyAuthenticator>で囲むだけでOK
↓必要なインポート (ルーティング分は除く)
import Amplify from "aws-amplify";
import { AmplifyAuthenticator } from "@aws-amplify/ui-react"
import awsconfig from "./aws-exports";
Amplify.configure(awsconfig);
描画処理部分
function App() {
return (
<AmplifyAuthenticator> //コレ
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route path="/test" component={Test} />
<Route path="/" component={Home} />
</Switch>
</Suspense>
</Router>
</AmplifyAuthenticator>
);
}
ルーティングで、/test と / の時が定義しているが、
ログインしていない時は、/test と / のどちらにアクセスしても認証フォームが表示される。