現役調理師がエンジニアを目指します3 (Recoil)

公開日
2022-11-16
投稿者
Ryousuke Kamei
#tag

Recoilの設定と選定理由


npm install Recoil

インストールの後

_app.jsの最上位コンポーネントを<RecoilRoot></RecoilRoot>でラップする。

export default function App({ Component, pageProps }: AppProps) {
  return (
    <RecoilRoot>
      <ChakraProvider theme={theme}>
        <Layout>
          <Component {...pageProps} />
        </Layout>
      </ChakraProvider>
    </RecoilRoot>
  )
}

これでアプリのどこからでもグローバルにアクセスできるようになる。

次にログイン用のモーダルを作成、グローバルで状態管理したいので


ルートにatomsフォルダを作成

その中に状態を管理したいものをファイル作成していく(複数でも問題ない)

今回はAuthModalAtom.tsを作成し、{ atom } をインポート

import { atom } from "recoil";

export interface AuthModalState {
    open: boolean;
    view: "ログイン" | "会員登録" | "パスワードの再設定"
};

const defaultAuthModal: AuthModalState = {
    open: false,
    view: "ログイン"
};

export const authModalState = atom<AuthModalState>({
    key: "authModalState",
    default: defaultAuthModal,
});


状態管理においてもバグが発生しないようinterfaceでしっかり型定義を

しておく事で、クラッシュする前にエラーに気づくことができ、また補完機能も使えるので

一石二鳥

作成ができたら、あとは使いたいコンポーネント内から、ファイルをインポートしてuseState

の感じで使う


import { authModalState } from '../../../atoms/AuthModalAtom'

const AuthModal = () => {
    const [ modalState , setModalState] = useRecoilState(authModalState)

    const handleClose = () => {
        setModalState((prev) => ({
            ...prev,
            open: false,
        }));
    };
    
    return (
        <>
            <Modal isOpen={modalState.open} onClose={handleClose}>
                <ModalOverlay />
                <ModalContent>
                <ModalHeader>モーダルのタイトル</ModalHeader>
                <ModalCloseButton />
                <ModalBody>ChakraUiのテンプレートモーダル</ModalBody>
                </ModalContent>
            </Modal>
        </>
    )
}
export default AuthModal


ChakraUiドキュメントから引っ張ってきたテンプレートモーダルに適用させる。

これでざっくりは完成

このテンプレートはカスタムして自分好みに作れるよう。便利


あとは別に作ったButtonにonClickuseSetRecoilState(状態管理したいAtomを引数に)を発火させグローバルで

状態管理を行う

const AuthButtons:React.FC = () => {

    const setAuthModalState = useSetRecoilState(authModalState);

    return (
        <>
            <Button 
                variant="outline" 
                height="28px" 
                display={{ base: "none", sm: "flex" }} 
                width={{ base: "70px", md: "110px" }} 
                mr={2} 
                onClick={() => setAuthModalState({ open: true, view: "ログイン"})}
                >ログイン
            </Button>
            <Button 
                height="26px" 
                display={{ base: "none", sm: "flex" }} 
                width={{ base: "70px", md: "110px" }} 
                mr={2}
                onClick={() => setAuthModalState({ open: true, view: "会員登録" })}
                >会員登録
            </Button>
        </>
    )
}

export default AuthButtons

一連の流れはこんな感じ。

バケツリレーのようにならず、飛び越えて管理できるので層が厚くなっても簡単にできました。

Reduxでの状態管理も試みましたが、圧倒的にRecoilの方が使いやすく感じた

chakra Ui

今回はほぼChakra Ui で構成

デザインに統一感があって、直感的にも使いやすいし、カスタムもできて

今回のModalだけでなく数多くのテンプレートがあってすごく効率も良くなると思います。