A reusable custom hook that manages Firebase authentication state with loading states and error handling.
import { useState, useEffect, useCallback, useMemo } from 'react';
import { User, onAuthStateChanged, signOut } from 'firebase/auth';
import { auth } from '../lib/firebase';
interface AuthState {
user: User | null;
loading: boolean;
error: string | null;
}
export function useAuth() {
const [authState, setAuthState] = useState<AuthState>({
user: null,
loading: true,
error: null
});
useEffect(() => {
const unsubscribe = onAuthStateChanged(
auth,
(user) => {
setAuthState({
user,
loading: false,
error: null
});
},
(error) => {
setAuthState({
user: null,
loading: false,
error: error.message
});
}
);
return unsubscribe;
}, []);
const logout = useCallback(async () => {
try {
setAuthState(prev => ({ ...prev, loading: true }));
await signOut(auth);
} catch (error) {
setAuthState(prev => ({
...prev,
loading: false,
error: error instanceof Error ? error.message : 'Logout failed'
}));
}
}, []);
const value = useMemo(() => ({
...authState,
logout,
isAuthenticated: !!authState.user
}), [authState, logout]);
return value;
}
Optimized with useCallback and useMemo to prevent unnecessary re-renders
A robust Next.js API route with comprehensive error handling, validation, and response formatting.
A React hook for real-time Firestore data with automatic subscription management and error handling.