FirebaseのUserをContext APIで管理する方法(React)
今回は、Firebase Authentication で取得した user objectを、React の Context API を用いてアプリケーション全体に渡す方法を紹介します。自分のアウトプット目的の記事ですが、もしも誰かの役に立てたなら幸いです。
※初学者向けの記事になります。
使用技術:React19, TypeScript, Firebase Authentication
Contents
Context APIとは?
状態をアプリケーション全体に渡すためのReactの仕組みです。かなり簡易に実装でき、user objectなど簡易なものの状態管理は、とりあえずContext APIで十分だと思います。
FirebaseのUserをContextで管理する
まずuseContextでContextを作成します。user objectとloading状態を管理しています。
import { createContext } from "react"; interface AuthContextType { user: User | null; loading: boolean; } const AuthContext = createContext<AuthContextType | undefined>(undefined);
Providerの実装
onAuthStateChanged
でFirebaseのログイン状態を監視します。userを検出したら setUser
で状態を更新します。FirebaseのonAuthStateChanged
は認証状況を監視し続けます。クリーンナップ関数でunsubscribe
を渡して、コンポーネントアンマウント時に監視を解除します。
Firebase ユーザー情報の取得
Child componentを、上で定義したAuthContext
のProvider
プロパティを用いて囲みます。
export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const [user, setUser] = useState<User | null>(null); const [loading, setLoading] = useState(true); useEffect(() => { const unsubscribe = onAuthStateChanged(auth, async (user) => { setUser(user); setLoading(false); }); return unsubscribe; }, []); return ( <AuthContext.Provider value={{ user, loading }}> {children} </AuthContext.Provider> ); };
Custom Hookの作成
Contextから値を取り出すCustom hookを用意しておくと便利です。
export const useAuthContext = () => { const context = useContext(AuthContext); if (context) { const { user, loading } = context; return { user, loading }; } else { throw new Error("useAuthContext must be used within AuthProvider"); } };
アプリ全体で使えるようにする
layout.tsx
に AuthProvider
をラップすることで、アプリケーション全体から useAuthContext()
を使って user を参照できるようになります。
// @/app/layout.tsx import { AuthProvider } from "@/context/auth-context"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <AuthProvider> {children} </AuthProvider> </body> </html> ); }
使い方
実際に useAuthContext
を使って、ログイン中のユーザー情報を表示する方法です。以下のように、どのコンポーネントでも簡単に user を使えます。
import { useAuthContext } from "@/context/auth-context"; //以下component function内 const { user, loading } = useAuthContext(); if (loading) { return <p>Loading...</p>; } if (!user) { return <p>ログインしてください</p>; } return <p>{user.displayName}さん、こんにちは!</p>;