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>;