【React】React-Admin Header Component をカスタマイズしてログアウトボタンを作成する

2022.07.07

はじめに

React-Adminは、Material Designを利用してAPI Baseのアプリを作成するFrontend Frameworkです。

Tutorialページを参考にアプリを作成した場合、ログイン画面、ログアウトボタンをサクッと実装することが可能です。

やりたいこと

(ログイン画面、)ログアウトボタンを自分でカスタマイズします。
と言いましても、既存のReact-Adminに利用されているログアウトのレイアウトは全く変わりません。

ログイン画面の実装につきましては、こちらの記事を参考にして頂けますと幸いです。

【React】Amplify UI Components でログイン画面を実装する

環境

  • react-admin: v4.2.1
  • @aws-amplify/ui-react: v3.0.3

実装コード

/src/App.tsx

import { Admin, Resource } from "react-admin";
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react';
import { AccountCreate, AccountList, AccountUpdate } from './components/Accounts';
import MyLayout from './components/MyLayout';
import AuthenticatorComponent from './components/AuthenticatorComponent';
import AuthenticatorFormFields from './components/AuthenticatorFormFields';
import dataProvider from './dataProvider';
import '@aws-amplify/ui-react/styles.css';

function App() {
  const { route } = useAuthenticator((context) => [context.user]);

  return route === 'authenticated' ? 
    <Admin dataProvider={dataProvider} layout={MyLayout}> // 自作のLayout Componentをココに追加
      <Resource
        name="Something"
        list={Something}
        create={Something}
        edit={Something}
      />
    </Admin> : <Authenticator formFields={AuthenticatorFormFields} components={AuthenticatorComponent} hideSignUp={true} />
}

MyLayout.tsx

import { memo } from 'react'
import {
  AppBar,
  Layout,
  Logout,
  UserMenu,
  LayoutProps,
  AppBarProps,
} from 'react-admin'
import { useAuthenticator } from '@aws-amplify/ui-react'

const CustomizedUserMenu = () => {
  const { signOut } = useAuthenticator((context) => [context.user])

  return (
    <UserMenu>
      <Logout onClick={signOut} />
    </UserMenu>
  )
}

const CustomizedAppBar = (props: AppBarProps) => (
  <AppBar {...props} userMenu={<CustomizedUserMenu />} />
)
const CustomizedAppBarMemo = memo(CustomizedAppBar)

const MyLayout = (props: LayoutProps) => (
  <Layout {...props} appBar={CustomizedAppBarMemo} />
)

export default MyLayout

経緯

Adding a Login Pageにも記載されているように、React-Adminでログイン/ログアウトを実装する場合には、authProvider object(ログイン/ログアウトの処理が書かれているオブジェクト)をpropsで渡す必要があります。
今回は、ログイン画面にAmplify UI Component(Authenticator hooks)を利用したため、authProvider objectを使わない方針にしました。 それに伴い、ログアウトの処理も消えるため、ログアウトボタンも表示されなくなってしまいます。ですので、ログアウトボタンをカスタマイズし、ログアウト処理はAmplify UI Component(Authenticator hooks)のsignOut関数を使うようにしました。
個人的には、authProvider objectをカスタマイズしても同じことは出来るとは思いますが、コードが少し複雑になるかなと思い、この方法を選択しました。

ポイント

リファレンスとGitHub exampleが大変参考になりましたので、下記に記載させていただきます。
型定義などは、CodeSandboxのexampleを参考に、他、エラーが出る部分は手探りで実装しました。

  • layout のカスタマイズ方法
  • GitHub example
    • https://github.com/marmelab/react-admin/tree/master/examples/simple
    • https://codesandbox.io/s/github/marmelab/react-admin/tree/master/examples/simple?file=/src/Layout.tsx

以上、どなたかの参考になりましたら幸いです。