# Select state efficiently

Use [`useShallow`](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/zustand-react-shallow#useshallow) when a selector builds an object or array from multiple state values and that result can remain shallowly equal across store updates. The component then keeps the same selected reference instead of re-rendering for an unchanged selection.

## Select multiple values

The store hook created with [`create`](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/zustand#create) compares selector results with `Object.is` by default. Wrap a selector that creates a new object or array in `useShallow` when updates to other state leave its contents shallowly equal.

Install Zustand and the React packages used by this example:

```bash
npm install zustand react react-dom
npm install --save-dev @types/react @types/react-dom
```

This React example selects two meal values in one object. The button changes a third value, so the meal summary stays selected as before and its render count does not increase; the separate meal display updates.

```tsx
import { useRef } from 'react'
import { createRoot } from 'react-dom/client'
import { create } from 'zustand'
import { useShallow } from 'zustand/react/shallow'

const useMeals = create(() => ({
  papaBear: 'large porridge-pot',
  mamaBear: 'middle-size porridge pot',
  littleBear: 'A little, small, wee pot',
}))

function MealSummary() {
  const { papaBear, mamaBear } = useMeals(
    useShallow((state) => ({
      papaBear: state.papaBear,
      mamaBear: state.mamaBear,
    })),
  )
  const renders = useRef(0)
  renders.current += 1

  return (
    <section>
      <h2>Meal summary</h2>
      <p>{papaBear}; {mamaBear}</p>
      <p>Meal summary renders: {renders.current}</p>
    </section>
  )
}

function LittleBearMeal() {
  const meal = useMeals((state) => state.littleBear)

  return (
    <section>
      <p>Little Bear's meal: {meal}</p>
      <button
        onClick={() => useMeals.setState({ littleBear: 'blueberry pancakes' })}
      >
        Change Little Bear's meal
      </button>
    </section>
  )
}

function App() {
  return (
    <main>
      <MealSummary />
      <LittleBearMeal />
    </main>
  )
}

const container = document.getElementById('app')
if (!container) {
  throw new Error('Expected an element with id="app"')
}

createRoot(container).render(<App />)
```

Put a mount element in the page's HTML before loading this React entry point:

```html
<div id="app"></div>
```

![The initial view shows the meal summary and its render count, Little Bear's meal, and the change button.](https://atloriaassets.blob.core.windows.net/assets/a438221c-c1af-407c-b9e6-a56c986db846/92d33a834d48189022981839f9394f30.png)

Initially, the summary shows Papa Bear and Mama Bear's meals and a render count of `1`. Click **Change Little Bear's meal**: Little Bear's displayed meal changes, while the summary and its count stay the same. The selector still creates a new object on each evaluation, but its selected properties have not changed, so `useShallow` returns the previous shallowly equal selection.

## Choose a selector

Use `useShallow` when an object or array returned by a selector may be shallowly equal to the previous result. Its argument is a selector `(state) => selectedValue`; it returns a selector you pass to the store hook. It does not prevent a render when a selected property itself changes.

| Selector result | Example | What the selection tracks |
| --- | --- | --- |
| Object of picks | `({ papaBear: state.papaBear, mamaBear: state.mamaBear })` | The picked values; an update outside these values leaves the selection equal. |
| Array of picks | `[state.papaBear, state.mamaBear]` | The values in order; a changed value or order changes the selection. |
| Computed keys | `Object.keys(state)` | The resulting keys; changing a value without changing keys leaves the selection equal. |

Shallow equality compares the top-level values, not nested contents. If a selected value changes, or the output is not shallowly equal, the component re-renders. A selector that returns a new reference without stabilizing it can cause unnecessary renders and, in v5, may cause an infinite loop. Use `useShallow` for shallowly equal outputs, or make the selector return a stable reference.

## See it running

Try the [Zustand live demo](https://zustand-demo.pmnd.rs/) to see a running Zustand app.

## Related

- [Selector subscriptions](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/selector-subscriptions)
- [Use custom equality functions](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/use-custom-equality-functions)
- [React quick start](https://bench-zustand-6l.atloria.app/p/bench-zustand-6l-TzFgfybqJX/developer/react-quick-start)
