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

# Component

> Base class for stateful Preact components

Base class for creating stateful, class-based components in Preact.

## Signature

```typescript theme={null}
abstract class Component<P = {}, S = {}> {
  constructor(props?: P, context?: any);
  
  // Instance properties
  props: RenderableProps<P>;
  state: Readonly<S>;
  context: any;
  
  // Core methods
  setState<K extends keyof S>(
    state: ((prevState: Readonly<S>, props: Readonly<P>) => Pick<S, K> | Partial<S> | null) | (Pick<S, K> | Partial<S> | null),
    callback?: () => void
  ): void;
  
  forceUpdate(callback?: () => void): void;
  
  abstract render(
    props?: RenderableProps<P>,
    state?: Readonly<S>,
    context?: any
  ): ComponentChildren;
  
  // Lifecycle methods
  componentWillMount?(): void;
  componentDidMount?(): void;
  componentWillUnmount?(): void;
  componentWillReceiveProps?(nextProps: Readonly<P>, nextContext: any): void;
  shouldComponentUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): boolean;
  componentWillUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): void;
  getSnapshotBeforeUpdate?(oldProps: Readonly<P>, oldState: Readonly<S>): any;
  componentDidUpdate?(previousProps: Readonly<P>, previousState: Readonly<S>, snapshot: any): void;
  componentDidCatch?(error: any, errorInfo: ErrorInfo): void;
  getChildContext?(): object;
  
  // Static methods
  static displayName?: string;
  static contextType?: Context<any>;
  static getDerivedStateFromProps?(props: Readonly<object>, state: Readonly<object>): object | null;
  static getDerivedStateFromError?(error: any): object | null;
}
```

## Type Parameters

<ParamField path="P" type="object" default="{}">
  The props type for the component.
</ParamField>

<ParamField path="S" type="object" default="{}">
  The state type for the component.
</ParamField>

## Constructor

```typescript theme={null}
constructor(props?: P, context?: any)
```

Creates a new component instance with the given props and context.

## Instance Properties

### props

```typescript theme={null}
props: RenderableProps<P>
```

The current props passed to the component. Includes `children` and optional `ref`.

### state

```typescript theme={null}
state: Readonly<S>
```

The current state of the component. Should only be modified via `setState()`.

### context

```typescript theme={null}
context: any
```

Context value from the nearest Provider ancestor, or the default value.

## Core Methods

### setState

```typescript theme={null}
setState<K extends keyof S>(
  state: ((prevState: Readonly<S>, props: Readonly<P>) => Pick<S, K> | Partial<S> | null) | (Pick<S, K> | Partial<S> | null),
  callback?: () => void
): void
```

Updates component state and schedules a re-render.

**Parameters:**

* `state`: Object to merge into state, or updater function receiving previous state and props
* `callback`: Optional function called after state update and re-render complete

**Implementation:** `src/component.js:34`

### forceUpdate

```typescript theme={null}
forceUpdate(callback?: () => void): void
```

Forces a synchronous re-render, bypassing `shouldComponentUpdate`.

**Parameters:**

* `callback`: Optional function called after re-render completes

**Implementation:** `src/component.js:69`

### render

```typescript theme={null}
abstract render(
  props?: RenderableProps<P>,
  state?: Readonly<S>,
  context?: any
): ComponentChildren
```

Returns the component's virtual DOM tree. Must be implemented by subclasses.

## Usage Examples

### Basic Component

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

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }
  
  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Increment
        </button>
      </div>
    );
  }
}
```

### With TypeScript

```tsx theme={null}
import { Component } from 'preact';

interface Props {
  initialCount: number;
  onCountChange?: (count: number) => void;
}

interface State {
  count: number;
}

class Counter extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { count: props.initialCount };
  }
  
  increment = () => {
    this.setState(
      (prevState) => ({ count: prevState.count + 1 }),
      () => {
        this.props.onCountChange?.(this.state.count);
      }
    );
  }
  
  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}
```

### Lifecycle Methods

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

class DataFetcher extends Component {
  state = { data: null, loading: true, error: null };
  
  componentDidMount() {
    // Fetch data after mount
    fetch('/api/data')
      .then(res => res.json())
      .then(data => this.setState({ data, loading: false }))
      .catch(error => this.setState({ error, loading: false }));
  }
  
  componentWillUnmount() {
    // Cleanup subscriptions, timers, etc.
    this.cleanup();
  }
  
  componentDidUpdate(prevProps, prevState) {
    // Respond to prop or state changes
    if (prevProps.id !== this.props.id) {
      this.fetchData(this.props.id);
    }
  }
  
  render() {
    const { data, loading, error } = this.state;
    
    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;
    return <div>{JSON.stringify(data)}</div>;
  }
}
```

### shouldComponentUpdate Optimization

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

class OptimizedList extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    // Only re-render if items array reference changed
    return this.props.items !== nextProps.items;
  }
  
  render() {
    return (
      <ul>
        {this.props.items.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    );
  }
}
```

### Error Boundaries

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

class ErrorBoundary extends Component {
  state = { hasError: false, error: null };
  
  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }
  
  componentDidCatch(error, errorInfo) {
    // Log error to service
    console.error('Error caught:', error, errorInfo);
  }
  
  render() {
    if (this.state.hasError) {
      return (
        <div>
          <h1>Something went wrong</h1>
          <details>
            <summary>Error details</summary>
            <pre>{this.state.error.toString()}</pre>
          </details>
        </div>
      );
    }
    
    return this.props.children;
  }
}
```

### Context 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>
    );
  }
}
```

## Lifecycle Method Order

### Mounting

1. `constructor()`
2. `static getDerivedStateFromProps()`
3. `render()`
4. `componentDidMount()`

### Updating

1. `static getDerivedStateFromProps()`
2. `shouldComponentUpdate()`
3. `render()`
4. `getSnapshotBeforeUpdate()`
5. `componentDidUpdate()`

### Unmounting

1. `componentWillUnmount()`

### Error Handling

1. `static getDerivedStateFromError()`
2. `componentDidCatch()`

## Legacy Lifecycle Methods

These methods are still supported but deprecated:

* `componentWillMount()` - Use `componentDidMount()` or `constructor()`
* `componentWillReceiveProps()` - Use `getDerivedStateFromProps()` or `componentDidUpdate()`
* `componentWillUpdate()` - Use `getSnapshotBeforeUpdate()` or `componentDidUpdate()`

## Implementation Details

The Component class is implemented in `src/component.js:19` as `BaseComponent`:

```javascript theme={null}
export function BaseComponent(props, context) {
  this.props = props;
  this.context = context;
  this._bits = 0;
}

BaseComponent.prototype.setState = function (update, callback) {
  // Implementation...
};

BaseComponent.prototype.forceUpdate = function (callback) {
  // Implementation...
};

BaseComponent.prototype.render = Fragment;
```

## Performance Notes

* `setState` uses shallow merging and batches multiple calls
* Re-renders are scheduled asynchronously via microtasks
* `forceUpdate` bypasses `shouldComponentUpdate` optimization
* State updates within `setState` callback see the updated state

## Related APIs

* [`render`](/api/render) - Mount components to the DOM
* [`Fragment`](/api/fragment) - Group multiple children
* [`createContext`](/api/create-context) - Create context for component tree
* `hooks` - Modern alternative to class components
