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

# PureComponent

> React PureComponent in Preact - component class with automatic shallow prop/state comparison

# PureComponent

A component class with a predefined `shouldComponentUpdate` implementation that performs shallow comparison of props and state.

## Signature

```typescript theme={null}
abstract class PureComponent<P = {}, S = {}> extends Component<P, S> {
  isPureReactComponent: boolean;
  shouldComponentUpdate(nextProps: Readonly<P>, nextState: Readonly<S>): boolean;
}
```

## Usage

### Basic Example

Extend `PureComponent` instead of `Component`:

```jsx theme={null}
import { PureComponent } from 'preact/compat';

class UserCard extends PureComponent {
  render() {
    const { name, email, avatar } = this.props;
    
    return (
      <div className="user-card">
        <img src={avatar} alt={name} />
        <h3>{name}</h3>
        <p>{email}</p>
      </div>
    );
  }
}

// This component will only re-render when props change
```

### With State

`PureComponent` also compares state changes:

```jsx theme={null}
import { PureComponent } from 'preact/compat';

class Counter extends PureComponent {
  state = {
    count: 0,
    label: 'Counter'
  };
  
  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };
  
  render() {
    return (
      <div>
        <h3>{this.state.label}</h3>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>+1</button>
      </div>
    );
  }
}
```

### TypeScript

Type your props and state:

```tsx theme={null}
import { PureComponent } from 'preact/compat';

interface TodoProps {
  id: number;
  text: string;
  completed: boolean;
  onToggle: (id: number) => void;
}

class TodoItem extends PureComponent<TodoProps> {
  handleClick = () => {
    this.props.onToggle(this.props.id);
  };
  
  render() {
    const { text, completed } = this.props;
    
    return (
      <li
        onClick={this.handleClick}
        style={{ textDecoration: completed ? 'line-through' : 'none' }}
      >
        {text}
      </li>
    );
  }
}
```

## Implementation Details

The `PureComponent` implementation in Preact:

```javascript theme={null}
export function PureComponent(p, c) {
  this.props = p;
  this.context = c;
}

PureComponent.prototype = new Component();
PureComponent.prototype.isPureReactComponent = true;
PureComponent.prototype.shouldComponentUpdate = function (props, state) {
  return shallowDiffers(this.props, props) || shallowDiffers(this.state, state);
};
```

### Shallow Comparison

The `shallowDiffers` function checks if objects differ:

```javascript theme={null}
function shallowDiffers(a, b) {
  for (let i in a) if (i !== '__source' && !(i in b)) return true;
  for (let i in b) if (i !== '__source' && a[i] !== b[i]) return true;
  return false;
}
```

This returns `true` if:

* Any keys exist in one object but not the other
* Any values differ using strict equality (`!==`)

## When to Use PureComponent

### Good Use Cases ✅

1. **Components with simple props**: Props that are primitives or stable references
2. **Frequently updated lists**: List items that receive the same props often
3. **Performance optimization**: Components that re-render unnecessarily

```jsx theme={null}
class ListItem extends PureComponent {
  render() {
    return <li>{this.props.text}</li>;
  }
}
```

### Problematic Cases ❌

1. **Props with new objects**: Creating new objects on every render defeats the purpose

```jsx theme={null}
// Bad: Creates new object every render
<UserCard user={{ name: 'John', age: 30 }} />

// Good: Use stable reference
const user = { name: 'John', age: 30 };
<UserCard user={user} />
```

2. **Props with new arrays**: New array references cause unnecessary re-renders

```jsx theme={null}
// Bad: Creates new array every render
<List items={this.state.data.map(x => x.name)} />

// Good: Memoize the array
const names = useMemo(
  () => this.state.data.map(x => x.name),
  [this.state.data]
);
<List items={names} />
```

3. **Props with inline functions**: New function references on every render

```jsx theme={null}
// Bad: Creates new function every render
<Button onClick={() => this.handleClick(item.id)} />

// Good: Use class method or memoized callback
<Button onClick={this.handleClick} />
```

## PureComponent vs Component

| Feature                 | Component                          | PureComponent                 |
| ----------------------- | ---------------------------------- | ----------------------------- |
| `shouldComponentUpdate` | Not implemented                    | Shallow comparison            |
| Re-renders              | On any `setState()` or prop change | Only when props/state differ  |
| Performance             | Baseline                           | Faster for stable props       |
| Use case                | Most components                    | Frequently updated components |

## PureComponent vs memo

* **PureComponent**: For class components
* **memo**: For functional components

```jsx theme={null}
// Class component
class UserCard extends PureComponent {
  render() {
    return <div>{this.props.name}</div>;
  }
}

// Functional component
const UserCard = memo(({ name }) => (
  <div>{name}</div>
));
```

Both provide similar optimization but for different component types.

## Overriding shouldComponentUpdate

You can override `shouldComponentUpdate` in a `PureComponent` for custom logic:

```jsx theme={null}
class CustomPure extends PureComponent {
  shouldComponentUpdate(nextProps, nextState) {
    // Custom comparison logic
    return this.props.userId !== nextProps.userId;
  }
  
  render() {
    return <div>{this.props.userName}</div>;
  }
}
```

**Note**: This defeats the purpose of `PureComponent`. Use regular `Component` instead.

## Common Patterns

### List Items

```jsx theme={null}
import { PureComponent } from 'preact/compat';

class TodoItem extends PureComponent {
  render() {
    const { todo, onToggle, onDelete } = this.props;
    
    return (
      <li>
        <input
          type="checkbox"
          checked={todo.completed}
          onChange={() => onToggle(todo.id)}
        />
        <span>{todo.text}</span>
        <button onClick={() => onDelete(todo.id)}>Delete</button>
      </li>
    );
  }
}

class TodoList extends Component {
  // Bind methods in constructor to maintain stable references
  constructor(props) {
    super(props);
    this.handleToggle = this.handleToggle.bind(this);
    this.handleDelete = this.handleDelete.bind(this);
  }
  
  handleToggle(id) {
    // Toggle logic
  }
  
  handleDelete(id) {
    // Delete logic
  }
  
  render() {
    return (
      <ul>
        {this.state.todos.map(todo => (
          <TodoItem
            key={todo.id}
            todo={todo}
            onToggle={this.handleToggle}
            onDelete={this.handleDelete}
          />
        ))}
      </ul>
    );
  }
}
```

### With Context

```jsx theme={null}
import { PureComponent, createContext } from 'preact/compat';

const ThemeContext = createContext('light');

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

## Identifying Pure Components

Check if a component is a `PureComponent`:

```jsx theme={null}
class MyComponent extends PureComponent {}

console.log(MyComponent.prototype.isPureReactComponent); // true
console.log(new MyComponent().isPureReactComponent); // true
```

## Best Practices

1. **Stable Props**: Ensure props are stable references or primitives
2. **Avoid Inline Objects**: Don't create new objects in render
3. **Avoid Inline Functions**: Use class methods or memoized callbacks
4. **Measure Performance**: Profile before and after to ensure it helps
5. **Consider Hooks**: For new code, consider using functional components with `memo` instead

## Migration to Functional Components

Modern Preact/React development favors functional components with hooks:

```jsx theme={null}
// Before: Class with PureComponent
class UserCard extends PureComponent {
  render() {
    return <div>{this.props.name}</div>;
  }
}

// After: Functional component with memo
import { memo } from 'preact/compat';

const UserCard = memo(({ name }) => (
  <div>{name}</div>
));
```

## Source

Implementation: compat/src/PureComponent.js:1-17
