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

# useMemo

> Returns a memoized value that only recomputes when dependencies change

`useMemo` returns a memoized value. It only recomputes the value when one of the dependencies has changed, helping to avoid expensive calculations on every render.

## Signature

```typescript theme={null}
function useMemo<T>(
  factory: () => T,
  inputs: ReadonlyArray<unknown> | undefined
): T
```

## Parameters

<ParamField path="factory" type="() => T" required>
  A function that computes and returns the value to be memoized. This function should be pure and take no arguments.
</ParamField>

<ParamField path="inputs" type="ReadonlyArray<unknown> | undefined" required>
  An array of dependencies. The memoized value will only be recomputed when one of these values changes (compared using `===`). If `undefined` is passed, a new value will be computed whenever a new function instance is passed as the first argument.
</ParamField>

## Returns

Returns the memoized value of type `T`. On the initial render, it returns the result of calling `factory()`. On subsequent renders, it returns the cached value if dependencies haven't changed, or recomputes by calling `factory()` if they have.

## Basic Usage

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

function ExpensiveComponent({ items }) {
  const [filter, setFilter] = useState('');

  // Only recompute when items or filter changes
  const filteredItems = useMemo(() => {
    console.log('Filtering items...');
    return items.filter(item =>
      item.name.toLowerCase().includes(filter.toLowerCase())
    );
  }, [items, filter]);

  return (
    <div>
      <input value={filter} onChange={e => setFilter(e.target.value)} />
      <ul>
        {filteredItems.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}
```

## Expensive Calculations

```jsx theme={null}
function DataAnalysis({ data }) {
  const statistics = useMemo(() => {
    console.log('Computing statistics...');
    return {
      mean: data.reduce((sum, val) => sum + val, 0) / data.length,
      max: Math.max(...data),
      min: Math.min(...data),
      sum: data.reduce((sum, val) => sum + val, 0)
    };
  }, [data]);

  return (
    <div>
      <p>Mean: {statistics.mean}</p>
      <p>Max: {statistics.max}</p>
      <p>Min: {statistics.min}</p>
      <p>Sum: {statistics.sum}</p>
    </div>
  );
}
```

## Memoizing Objects

```jsx theme={null}
function UserProfile({ userId, userName }) {
  // Prevent creating a new object on every render
  const user = useMemo(() => ({
    id: userId,
    name: userName,
    lastSeen: Date.now()
  }), [userId, userName]);

  return <ExpensiveChildComponent user={user} />;
}
```

## Sorting and Filtering

```jsx theme={null}
function ProductList({ products, sortBy, searchTerm }) {
  const displayedProducts = useMemo(() => {
    let result = products;

    // Filter
    if (searchTerm) {
      result = result.filter(p =>
        p.name.toLowerCase().includes(searchTerm.toLowerCase())
      );
    }

    // Sort
    result = [...result].sort((a, b) => {
      if (sortBy === 'price') return a.price - b.price;
      if (sortBy === 'name') return a.name.localeCompare(b.name);
      return 0;
    });

    return result;
  }, [products, sortBy, searchTerm]);

  return (
    <ul>
      {displayedProducts.map(product => (
        <li key={product.id}>{product.name} - ${product.price}</li>
      ))}
    </ul>
  );
}
```

## Computing Derived State

```jsx theme={null}
function ShoppingCart({ items }) {
  const summary = useMemo(() => {
    const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
    const tax = subtotal * 0.1;
    const shipping = subtotal > 100 ? 0 : 10;
    const total = subtotal + tax + shipping;

    return { subtotal, tax, shipping, total };
  }, [items]);

  return (
    <div>
      <p>Subtotal: ${summary.subtotal.toFixed(2)}</p>
      <p>Tax: ${summary.tax.toFixed(2)}</p>
      <p>Shipping: ${summary.shipping.toFixed(2)}</p>
      <p>Total: ${summary.total.toFixed(2)}</p>
    </div>
  );
}
```

## Referential Equality

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

// Child component only re-renders if style object reference changes
const ExpensiveChild = memo(({ style }) => {
  console.log('Child rendered');
  return <div style={style}>Expensive component</div>;
});

function Parent({ color }) {
  // Memoize style object to prevent unnecessary child re-renders
  const style = useMemo(() => ({
    backgroundColor: color,
    padding: '20px',
    borderRadius: '8px'
  }), [color]);

  return <ExpensiveChild style={style} />;
}
```

## Creating Regex Patterns

```jsx theme={null}
function SearchableList({ items, pattern }) {
  const regex = useMemo(() => {
    try {
      return new RegExp(pattern, 'i');
    } catch {
      return null;
    }
  }, [pattern]);

  const filteredItems = useMemo(() => {
    if (!regex) return items;
    return items.filter(item => regex.test(item.name));
  }, [items, regex]);

  return (
    <ul>
      {filteredItems.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}
```

## Graph Computations

```jsx theme={null}
function SocialGraph({ users, connections }) {
  const adjacencyList = useMemo(() => {
    const graph = new Map();

    users.forEach(user => {
      graph.set(user.id, new Set());
    });

    connections.forEach(([from, to]) => {
      graph.get(from)?.add(to);
      graph.get(to)?.add(from);
    });

    return graph;
  }, [users, connections]);

  const getMutualFriends = (userId1, userId2) => {
    const friends1 = adjacencyList.get(userId1) || new Set();
    const friends2 = adjacencyList.get(userId2) || new Set();

    return [...friends1].filter(id => friends2.has(id));
  };

  return <div>{/* Use adjacencyList */}</div>;
}
```

## With undefined Dependencies

```jsx theme={null}
function Component({ computeFn }) {
  // Recompute whenever computeFn reference changes
  const result = useMemo(() => {
    return computeFn();
  }, undefined);

  return <div>{result}</div>;
}
```

<Note>
  `useMemo` is an optimization tool. Your code should work correctly without it, then add it to improve performance where needed.
</Note>

<Note>
  Don't use `useMemo` for everything. It has overhead, so only use it for computationally expensive operations or when maintaining referential equality is important for child component optimization.
</Note>

<Note>
  Unlike React, Preact requires the `inputs` parameter. Pass `undefined` explicitly if you want to recompute whenever the factory function changes.
</Note>
