> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/preactjs/preact/llms.txt
> Use this file to discover all available pages before exploring further.

# useContext

> Returns the current value for a context

`useContext` returns the current context value for the given context. The value is determined by the nearest `<Context.Provider>` above the calling component in the tree.

## Signature

```typescript theme={null}
function useContext<T>(context: PreactContext<T>): T
```

## Parameters

<ParamField path="context" type="PreactContext<T>" required>
  The context object created by `createContext`. The hook reads the current value from the nearest provider for this context.
</ParamField>

## Returns

Returns the current context value of type `T`. The value is determined by the `value` prop of the nearest `<Context.Provider>` above the calling component. If there is no provider, the default value passed to `createContext` is returned.

## Basic Usage

```jsx theme={null}
import { createContext } from 'preact';
import { useContext } from 'preact/hooks';

const ThemeContext = createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return (
    <button className={`theme-${theme}`}>
      I am styled by theme context
    </button>
  );
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}
```

## Multiple Contexts

```jsx theme={null}
const ThemeContext = createContext('light');
const UserContext = createContext(null);
const LanguageContext = createContext('en');

function UserProfile() {
  const theme = useContext(ThemeContext);
  const user = useContext(UserContext);
  const language = useContext(LanguageContext);

  return (
    <div className={`theme-${theme}`}>
      <h1>{language === 'en' ? 'Welcome' : 'Bienvenido'}</h1>
      <p>{user?.name}</p>
    </div>
  );
}

function App() {
  const [user, setUser] = useState({ name: 'John' });

  return (
    <ThemeContext.Provider value="dark">
      <UserContext.Provider value={user}>
        <LanguageContext.Provider value="en">
          <UserProfile />
        </LanguageContext.Provider>
      </UserContext.Provider>
    </ThemeContext.Provider>
  );
}
```

## With TypeScript

```typescript theme={null}
import { createContext } from 'preact';
import { useContext } from 'preact/hooks';

interface Theme {
  primary: string;
  secondary: string;
  background: string;
}

const ThemeContext = createContext<Theme>({
  primary: '#007bff',
  secondary: '#6c757d',
  background: '#ffffff'
});

function ThemedComponent() {
  const theme = useContext(ThemeContext);

  return (
    <div style={{ backgroundColor: theme.background }}>
      <button style={{ color: theme.primary }}>Primary</button>
      <button style={{ color: theme.secondary }}>Secondary</button>
    </div>
  );
}
```

## Updating Context Value

```jsx theme={null}
import { createContext } from 'preact';
import { useContext, useState } from 'preact/hooks';

const ThemeContext = createContext({
  theme: 'light',
  toggleTheme: () => {}
});

function ThemeToggle() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <button onClick={toggleTheme}>
      Current theme: {theme}
    </button>
  );
}

function App() {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      <ThemeToggle />
    </ThemeContext.Provider>
  );
}
```

## Authentication Context

```jsx theme={null}
const AuthContext = createContext({
  user: null,
  login: () => {},
  logout: () => {}
});

function useAuth() {
  return useContext(AuthContext);
}

function LoginButton() {
  const { user, login, logout } = useAuth();

  if (user) {
    return (
      <div>
        <span>Welcome, {user.name}</span>
        <button onClick={logout}>Logout</button>
      </div>
    );
  }

  return <button onClick={login}>Login</button>;
}

function App() {
  const [user, setUser] = useState(null);

  const login = async () => {
    const userData = await fetchUser();
    setUser(userData);
  };

  const logout = () => {
    setUser(null);
  };

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      <LoginButton />
    </AuthContext.Provider>
  );
}
```

## Complex State in Context

```jsx theme={null}
const AppContext = createContext();

function reducer(state, action) {
  switch (action.type) {
    case 'set-user':
      return { ...state, user: action.payload };
    case 'set-theme':
      return { ...state, theme: action.payload };
    case 'add-notification':
      return {
        ...state,
        notifications: [...state.notifications, action.payload]
      };
    default:
      return state;
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, {
    user: null,
    theme: 'light',
    notifications: []
  });

  return (
    <AppContext.Provider value={{ state, dispatch }}>
      {/* App components */}
    </AppContext.Provider>
  );
}

function SomeComponent() {
  const { state, dispatch } = useContext(AppContext);

  const notify = (message) => {
    dispatch({ type: 'add-notification', payload: message });
  };

  return <div>{state.theme}</div>;
}
```

<Note>
  When the `value` prop of the nearest `<Context.Provider>` updates, all components that call `useContext` with that context will re-render, even if their parent would normally prevent re-rendering.
</Note>

<Note>
  The context value is always taken from the nearest provider above the component. Context does not "tunnel" through intermediate components.
</Note>

<Note>
  If there is no provider for a context above the component, `useContext` returns the default value that was passed to `createContext`.
</Note>
