> ## 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.

# createContext

> Create a Context for passing data through the component tree

Creates a Context object for passing data through the component tree without manually passing props at every level.

## Signature

```typescript theme={null}
function createContext<T>(defaultValue: T): Context<T>
```

## Parameters

<ParamField path="defaultValue" type="T" required>
  The default value used when a component does not have a matching Provider above it in the tree.
</ParamField>

## Return Value

Returns a `Context<T>` object with the following properties:

```typescript theme={null}
interface Context<T> {
  Provider: Provider<T>;
  Consumer: Consumer<T>;
  displayName?: string;
}

interface Provider<T> extends FunctionComponent<{
  value: T;
  children?: ComponentChildren;
}> {}

interface Consumer<T> extends FunctionComponent<{
  children: (value: T) => ComponentChildren;
}> {}
```

## Description

`createContext` creates a Context object that allows you to share values between components without explicitly passing props through every level of the tree.

The Context object includes:

* **Provider**: Component that provides the context value
* **Consumer**: Component that consumes the context value

Components that consume context will re-render when the Provider's value changes.

## Implementation

The function is implemented in `src/create-context.js:6`:

```javascript theme={null}
export function createContext(defaultValue) {
  function Context(props) {
    if (!this.getChildContext) {
      let subs = new Set();
      let ctx = {};
      ctx[Context._id] = this;

      this.getChildContext = () => ctx;

      this.componentWillUnmount = () => {
        subs = NULL;
      };

      this.shouldComponentUpdate = function (_props) {
        if (this.props.value != _props.value) {
          subs.forEach(c => {
            c._bits |= COMPONENT_FORCE;
            enqueueRender(c);
          });
        }
      };

      this.sub = c => {
        subs.add(c);
        let old = c.componentWillUnmount;
        c.componentWillUnmount = () => {
          if (subs) {
            subs.delete(c);
          }
          if (old) old.call(c);
        };
      };
    }

    return props.children;
  }

  Context._id = '__cC' + i++;
  Context._defaultValue = defaultValue;
  Context.Consumer = (props, contextValue) => {
    return props.children(contextValue);
  };
  Context.Provider = Context._contextRef = Context.Consumer.contextType = Context;

  return Context;
}
```

## Usage Examples

### Basic Context

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

// Create context
const ThemeContext = createContext('light');

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

// Consumer with hooks
function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div className={`toolbar-${theme}`}>Toolbar</div>;
}
```

### With Consumer Component

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

const UserContext = createContext(null);

function App() {
  const user = { name: 'John Doe', role: 'admin' };
  
  return (
    <UserContext.Provider value={user}>
      <Profile />
    </UserContext.Provider>
  );
}

function Profile() {
  return (
    <UserContext.Consumer>
      {user => (
        <div>
          <h1>{user.name}</h1>
          <p>Role: {user.role}</p>
        </div>
      )}
    </UserContext.Consumer>
  );
}
```

### Complex Context Value

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

const AppContext = createContext({
  theme: 'light',
  user: null,
  setTheme: () => {},
  setUser: () => {}
});

function AppProvider({ children }) {
  const [theme, setTheme] = useState('light');
  const [user, setUser] = useState(null);
  
  const value = {
    theme,
    user,
    setTheme,
    setUser
  };
  
  return (
    <AppContext.Provider value={value}>
      {children}
    </AppContext.Provider>
  );
}
```

### Multiple Contexts

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

const ThemeContext = createContext('light');
const UserContext = createContext(null);

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <UserContext.Provider value={{ name: 'Alice' }}>
        <Dashboard />
      </UserContext.Provider>
    </ThemeContext.Provider>
  );
}

function Dashboard() {
  const theme = useContext(ThemeContext);
  const user = useContext(UserContext);
  
  return (
    <div className={`dashboard-${theme}`}>
      Welcome, {user.name}!
    </div>
  );
}
```

### With TypeScript

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

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

const defaultTheme: Theme = {
  primary: '#007bff',
  secondary: '#6c757d',
  background: '#ffffff'
};

const ThemeContext = createContext<Theme>(defaultTheme);

function ThemedButton() {
  const theme = useContext(ThemeContext);
  
  return (
    <button style={{ backgroundColor: theme.primary }}>
      Click me
    </button>
  );
}
```

### Class Component Consumer

```jsx theme={null}
import { Component, createContext } from 'preact';

const ThemeContext = createContext('light');

class ThemedButton extends Component {
  static contextType = ThemeContext;
  
  render() {
    const theme = this.context;
    return (
      <button className={`button-${theme}`}>
        {this.props.children}
      </button>
    );
  }
}
```

### Dynamic Context Updates

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

const CountContext = createContext({ count: 0, increment: () => {} });

function CountProvider({ children }) {
  const [count, setCount] = useState(0);
  
  const value = {
    count,
    increment: () => setCount(c => c + 1)
  };
  
  return (
    <CountContext.Provider value={value}>
      {children}
    </CountContext.Provider>
  );
}

function Counter() {
  const { count, increment } = useContext(CountContext);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}
```

### Nested Providers

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

const ThemeContext = createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <OuterComponent />
      <ThemeContext.Provider value="light">
        <InnerComponent />
      </ThemeContext.Provider>
    </ThemeContext.Provider>
  );
}

function OuterComponent() {
  const theme = useContext(ThemeContext); // "dark"
  return <div className={theme}>Outer</div>;
}

function InnerComponent() {
  const theme = useContext(ThemeContext); // "light"
  return <div className={theme}>Inner</div>;
}
```

## Best Practices

### Separate Context Creation

```jsx theme={null}
// contexts/ThemeContext.js
import { createContext } from 'preact';

export const ThemeContext = createContext('light');

// App.js
import { ThemeContext } from './contexts/ThemeContext';

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

### Custom Hook for Context

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

const AuthContext = createContext(null);

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

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  
  return (
    <AuthContext.Provider value={{ user, setUser }}>
      {children}
    </AuthContext.Provider>
  );
}
```

### Avoid Unnecessary Re-renders

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

const AppContext = createContext(null);

function AppProvider({ children }) {
  const [state, setState] = useState({ count: 0 });
  
  // Memoize the context value to prevent unnecessary re-renders
  const value = useMemo(() => ({
    state,
    increment: () => setState(s => ({ count: s.count + 1 }))
  }), [state]);
  
  return (
    <AppContext.Provider value={value}>
      {children}
    </AppContext.Provider>
  );
}
```

## Default Value Usage

The default value is used when no Provider is found:

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

// Without Provider
function App() {
  return <ThemedDiv />; // Uses 'light' default
}

// With Provider
function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedDiv /> {/* Uses 'dark' from Provider */}
    </ThemeContext.Provider>
  );
}

function ThemedDiv() {
  const theme = useContext(ThemeContext);
  return <div className={theme}>Content</div>;
}
```

## Performance Considerations

* Context updates trigger re-renders of all consuming components
* Use multiple contexts to separate concerns and reduce re-renders
* Memoize context values when they're computed or include functions
* Consider using state management libraries for complex state

## Related APIs

* `useContext` hook - Consume context in function components
* [`Component`](/api/component) - Class components with `contextType`
* [`Fragment`](/api/fragment) - Group elements without wrapper
