@aws-amplify/ui-reactでSignUpフォームをカスタマイズする

@aws-amplify/ui-reactを使っている場合、AmplifyAuthenticatorAmplifySignUpコンポーネントを使うことでアカウント作成(SignUp)の実装はほぼ片付きます。

が、独自のバリデーションや処理を追加したい場合には、少しカスタムする必要がでてきます。

handleSubmitを独自処理に置き換えたコード

若干横着していますが、AmplifySignUpとほぼ似た挙動をするCustomSignUpコンポーネントです。

import {
  AmplifyAuthenticator,
  AmplifySignUp,
 } from '@aws-amplify/ui-react';
 import {
 UI_AUTH_CHANNEL,
 AUTH_STATE_CHANGE_EVENT
import {
 Auth,
 Hub 
} from 'aws-amplify';

const dispatchAuthStateChangeEvent = (nextAuthState: AuthState, data?: object) => {
  Hub.dispatch(UI_AUTH_CHANNEL, {
    event: AUTH_STATE_CHANGE_EVENT,
    message: nextAuthState,
    data,
  });
};


const CustomSignUp: FC = () => {
  const [userData, updateUserData] = useState<{
    username?: string;
    email?: string;
    password?: string;
  }>({})
  const handleUserDataChange = (type: 'username' | 'email' | 'password', value: string) => {
    updateUserData({
      ...userData,
      [type]: value
    })
  }
  const handleSubmit = (e: Event) => {
    e.preventDefault()
    console.log(userData)
    if (!userData.username || !userData.password) return;
    Auth.signUp({
      username: userData.username,
      password: userData.password,
      attributes: {
        email: userData.email
      }
    }).then(data => {
      dispatchAuthStateChangeEvent(AuthState.ConfirmSignUp, data)
    })
  }
  return (
    <AmplifySignUp
      slot="sign-up"
      formFields={[
        {
          handleInputChange: (e: any) => {
            handleUserDataChange('username', e.target.value)
          },
          type: "username",
       },
        {
          handleInputChange:  (e: any) => {
            handleUserDataChange('email', e.target.value)
          },
          type: "email",
       },
        {
          handleInputChange:  (e: any) => {
            handleUserDataChange('password', e.target.value)
          },
          type: "password",
       },
      ]}
      handleSubmit={handleSubmit}
    />
  )
}

実装のポイント

formFieldsでFormの設定と値のハンドルを行う

handleSubmitを自前で実行する関係上、Auth.SignUpに必要な値のハンドルが必要です。AmplifySignUpを利用する場合、formFieldsで表示したいフィールドを定義する際に、handleInputChangeを実装してuseStateなどと組み合わせることで、各フィールドの値をハンドルできるようになります。

Hub.dispatchで確認コード入力に切り替える

handleSubmitAuth.signUpを呼び出せばアカウント作成自体は完了します。が、この後Hub.dispatchを実行することで、AmplifyAuthenticatorが自動で確認コード入力のフォームを表示してくれるようになります。以下の関数がSDK内部で再利用されていましたので、exportされるまでは自前でこれを作る形での対応になりそうです。

const dispatchAuthStateChangeEvent = (nextAuthState: AuthState, data?: object) => {
  Hub.dispatch(UI_AUTH_CHANNEL, {
    event: AUTH_STATE_CHANGE_EVENT,
    message: nextAuthState,
    data,
  });
};

Comment