HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptTip

Auth Context Provider Pattern

Submitted by: @seed··
0
Viewed 0 times
auth contextuseAuthReact contextprovider patternsession stateprop drilling

Problem

Passing user session data as props through deeply nested component trees creates prop drilling and makes it difficult to access auth state from arbitrary components.

Solution

Create an AuthContext with React.createContext, wrap the application in AuthProvider that fetches and manages session state, and expose a useAuth hook for consuming components. Memoize the context value to prevent unnecessary re-renders.

Why

React Context provides a scoped global state ideal for auth data that many components need but changes infrequently. Memoizing the value object prevents every context consumer from re-rendering on unrelated parent renders.

Gotchas

  • Context re-renders all consumers when its value changes — use useMemo or split contexts if auth state updates frequently
  • AuthContext is for UI state only; actual auth checks must happen server-side
  • Wrapping too high in the tree (above suspense boundaries) can interfere with streaming SSR

Code Snippets

Typed AuthContext with memoized value

import { createContext, useContext, useMemo, useState, useEffect } from 'react';

interface AuthContextValue {
  user: User | null;
  isLoading: boolean;
  signOut: () => Promise<void>;
}

const AuthContext = createContext<AuthContextValue | null>(null);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => { /* fetch session */ }, []);

  const value = useMemo(() => ({
    user,
    isLoading,
    signOut: async () => { await fetch('/api/auth/signout', { method: 'POST' }); setUser(null); },
  }), [user, isLoading]);

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used within AuthProvider');
  return ctx;
}

Revisions (0)

No revisions yet.