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

# Components

> Learn about Preact components, including functional and class-based components, props, and state management

Components are the building blocks of Preact applications. They let you split your UI into independent, reusable pieces.

## Component types

Preact supports two types of components:

<Tabs>
  <Tab title="Functional components">
    Functional components are simple JavaScript functions that accept props and return JSX.

    ```jsx theme={null}
    function Greeting({ name }) {
      return <h1>Hello, {name}!</h1>;
    }
    ```

    This is the recommended approach for most components. They are simpler, easier to test, and work seamlessly with hooks.
  </Tab>

  <Tab title="Class components">
    Class components extend from Preact's `Component` base class and have additional features like lifecycle methods and local state.

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

    class Greeting extends Component {
      render() {
        return <h1>Hello, {this.props.name}!</h1>;
      }
    }
    ```
  </Tab>
</Tabs>

## The Component class

Preact exports a `BaseComponent` class (aliased as `Component`) that provides core functionality for class-based components. Here's how it's defined in `src/component.js:19`:

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

The Component class provides two key methods:

### setState()

Updates component state and schedules a re-render:

```javascript theme={null}
BaseComponent.prototype.setState = function (update, callback) {
  let s;
  if (this._nextState != NULL && this._nextState != this.state) {
    s = this._nextState;
  } else {
    s = this._nextState = assign({}, this.state);
  }

  if (typeof update == 'function') {
    update = update(assign({}, s), this.props);
  }

  if (update) {
    assign(s, update);
  } else {
    return;
  }

  if (this._vnode) {
    if (callback) {
      this._stateCallbacks.push(callback);
    }
    enqueueRender(this);
  }
};
```

### forceUpdate()

Immediately triggers a re-render, bypassing `shouldComponentUpdate()`:

```javascript theme={null}
BaseComponent.prototype.forceUpdate = function (callback) {
  if (this._vnode) {
    this._bits |= COMPONENT_FORCE;
    if (callback) this._renderCallbacks.push(callback);
    enqueueRender(this);
  }
};
```

## Props

Props (short for "properties") are arguments passed to components. They are read-only and flow down from parent to child.

```jsx theme={null}
function Welcome({ name, age }) {
  return (
    <div>
      <p>Name: {name}</p>
      <p>Age: {age}</p>
    </div>
  );
}

// Usage
<Welcome name="Alice" age={30} />
```

### Props in class components

In class components, props are available via `this.props`:

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

class Welcome extends Component {
  render() {
    return (
      <div>
        <p>Name: {this.props.name}</p>
        <p>Age: {this.props.age}</p>
      </div>
    );
  }
}
```

## State

State is private data managed within a component. When state changes, the component re-renders.

### State in class components

Here's a real example from Preact's demo code (`demo/todo.jsx:5`):

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

class TodoList extends Component {
  state = { todos: [], text: '' };

  setText = e => {
    this.setState({ text: e.target.value });
  };

  addTodo = () => {
    let { todos, text } = this.state;
    todos = todos.concat({ text, id: ++counter });
    this.setState({ todos, text: '' });
  };

  render({}, { todos, text }) {
    return (
      <form onSubmit={this.addTodo} action="javascript:">
        <input value={text} onInput={this.setText} />
        <button type="submit">Add</button>
        <ul>
          {todos.map(todo => (
            <li key={todo.id}>{todo.text}</li>
          ))}
        </ul>
      </form>
    );
  }
}
```

<Note>
  The `render()` method can destructure both props and state from its arguments for cleaner code.
</Note>

### Updating state

You can pass an object or a function to `setState()`:

<CodeGroup>
  ```jsx Object update theme={null}
  this.setState({ count: 5 });
  ```

  ```jsx Function update theme={null}
  this.setState((state, props) => ({
    count: state.count + 1
  }));
  ```
</CodeGroup>

<Warning>
  Never modify state directly. Always use `setState()` to ensure the component re-renders correctly.
</Warning>

## Functional vs class components

Here's the same component implemented both ways:

<Tabs>
  <Tab title="Functional (with hooks)">
    ```jsx theme={null}
    import { useState } from 'preact/hooks';

    function Counter() {
      const [count, setCount] = useState(0);

      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={() => setCount(count + 1)}>
            Increment
          </button>
        </div>
      );
    }
    ```
  </Tab>

  <Tab title="Class-based">
    ```jsx theme={null}
    import { Component } from 'preact';

    class Counter extends Component {
      state = { count: 0 };

      increment = () => {
        this.setState({ count: this.state.count + 1 });
      };

      render() {
        return (
          <div>
            <p>Count: {this.state.count}</p>
            <button onClick={this.increment}>
              Increment
            </button>
          </div>
        );
      }
    }
    ```
  </Tab>
</Tabs>

## Real-world example

Here's a complete example from Preact's demo showing both component types working together (`demo/context.jsx:5`):

```jsx theme={null}
import { Component, createContext } from 'preact';
const { Provider, Consumer } = createContext();

class ThemeProvider extends Component {
  state = {
    value: this.props.value
  };

  onClick = () => {
    this.setState(prev => ({
      value: prev.value === this.props.value 
        ? this.props.next 
        : this.props.value
    }));
  };

  render() {
    return (
      <div>
        <button onClick={this.onClick}>Toggle</button>
        <Provider value={this.state.value}>
          {this.props.children}
        </Provider>
      </div>
    );
  }
}

class Child extends Component {
  shouldComponentUpdate() {
    return false;
  }

  render() {
    return (
      <>
        <p>(blocked update)</p>
        {this.props.children}
      </>
    );
  }
}
```

<Info>
  This example demonstrates prop passing, state management, lifecycle methods, and component composition.
</Info>

## Component render queue

When you call `setState()` or `forceUpdate()`, Preact doesn't immediately re-render the component. Instead, it adds the component to a render queue (`src/component.js:185`):

```javascript theme={null}
let rerenderQueue = [];

export function enqueueRender(c) {
  if (
    (!(c._bits & COMPONENT_DIRTY) &&
      (c._bits |= COMPONENT_DIRTY) &&
      rerenderQueue.push(c) &&
      !rerenderCount++) ||
    prevDebounce != options.debounceRendering
  ) {
    prevDebounce = options.debounceRendering;
    (prevDebounce || queueMicrotask)(process);
  }
}
```

This batching mechanism ensures efficient rendering by processing multiple updates together.
