Recoil設定
Recoilのインストール
npm install recoil
Recoil の設定
Recoilを使うためには一番トップのコンポーネントにRecoilRootというコンポーネントでラップする必要がある。
layout.tsxに'use client'をつけて、クライアントコンポーネントにするとApp Routerのメリットが得られなくなるため、Compositionを利用する。
src/app/recoilProvider.tsx
'use client'
import { ReactNode } from 'react';
import { RecoilRoot } from 'recoil';
function RecoilProvider({ children }: { children: ReactNode }) {
return (
<RecoilRoot>{children}</RecoilRoot>
);
}
export default RecoilProvider;
src/app/layout.tsx
'use client';
//import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import RecoilProvider from './recoilProvider'; //別ファイルで作成したRecoilProviderをインポート
import './globals.css';
const inter = Inter({ subsets: ['latin'] });
// export const metadata: Metadata = {
// title: 'Create Next App',
// description: 'Generated by create next app',
// };
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang='en'>
<body className={inter.className}>
<RecoilProvider>{children}</RecoilProvider>
</body>
</html>
);
}
atomの作成
Recoilの状態管理の核である、atom(グローバルstate)を作成
- Recoilでは、stateをatomという単位で構成する
- 以下では例として、ユーザーの情報を管理するatomを作成
- keyの値はユニーク
- atomとして設定した値は全コンポーネント間で状態が共有される
- atomの値が更新されると、その値を使用しているコンポーネント全てに再レンダリングが走る
以下例
src/atoms/userState.ts
import { atom } from 'recoil'
export type User = {
id: number;
name: string;
email: string;
};
export const userState = atom<User[]>({
key: 'userState',
default: {
id: null,
name: '',
email: ''
}
})
stateを使うコンポーネント例
設定する場合
...
import { useSetRecoilState } from 'recoil';
import { User, userState } from '@/atoms/userState';
export const AuthUser: React.FC = () => {
const setUser = useSetRecoilState(userState);
const login = () => {
if (検証) {
return;
}
setUser (
{
id: アイディー,
name: ナマエ,
email: メール
},
);
return
};
...
使う場合
import { useRecoilValue } from 'recoil';
import { userState } from '@/atoms/userState';
export const Hoge: React.FC = () => {
const user = useRecoilValue(userState);
return (
<>
<div>user.id</div>
<div>user.name</div>
<div>user.email</div>
</>
);
};