Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Zustand · Const

memoized selectors

useShallow wraps a Zustand selector with shallow-result memoization. It helps React components avoid re-rendering when selected object or array contents have not changed.

Since
v5

How it works

useShallow wraps a selector and returns a memoized selector whose selected result is compared shallowly. This is useful when a selector creates a new object or array reference, because unchanged selected values can retain the previous result and avoid an unnecessary component re-render.

Syntax

const memoizedSelector = useShallow(selector)

Parameters

NameTypeDescription
selectorFn(state: T) => UA selector function that receives the current state and returns the data to select.

Returns

A memoized selector function with type (state: T) => U.

Key points

  • useShallow is intended for React components that need fewer re-renders from selector results.
  • Create a memoized selector by passing the original selector to useShallow.
  • The generic signature preserves the selector's state input and selected-result output types.
  • The selector function derives the value returned to the component from the current store state.
  • Memoization uses shallow comparison, making unchanged selected properties reusable even when the enclosing result would otherwise be recreated.
  • For collections such as Object.keys(state), rendering can be limited to changes in the actual selected keys.

Common mistakes

  • With Zustand v5, a selector that creates a fresh object or array every render can cause an infinite update loop because the default equality check uses Object.is. Wrap it with useShallow or select each value separately.

Example: Select multiple fields with shallow memoization

import { create } from 'zustand'
import { useShallow } from 'zustand/react/shallow'

type Store = {
  nuts: number
  honey: number
  addNuts: (n: number) => void
}

const useBearStore = create<Store>((set) => ({
  nuts: 1,
  honey: 2,
  addNuts: (n) => set((state) => ({ nuts: state.nuts + n })),
}))

export function BearSummary() {
  const summary = useBearStore(
    useShallow((state) => ({ nuts: state.nuts, honey: state.honey })),
  )
  return <p>{summary.nuts} nuts, {summary.honey} honey</p>
}

The component selects two fields through a shallow-memoized selector, so changes elsewhere in the store do not cause it to re-render.

When to use it

Stable derived collections

A selector returns Object.keys(state), producing a new array while the keys remain unchanged.

Multiple-field selection

A component needs several store fields grouped into one object.

Avoiding unnecessary re-renders

A selector constructs a small object or array on each evaluation.

Interview questions

QWhat does useShallow do?

useShallow is a React Hook that accepts a selector function and returns a memoized selector. The returned selector uses shallow comparison to decide whether the selected result has meaningfully changed.

Follow-up: What alternative avoids creating a wrapper object? Subscribe to each selected value with its own selector, so no wrapper object needs to be recreated.

QWhen should a selector be memoized with useShallow?

It is useful when a selector returns a newly allocated object or array, such as Object.keys(state) or an object containing several fields. Shallow comparison checks the selected entries rather than requiring the outer reference itself to remain identical.

Follow-up: When should it be avoided? If selecting individual fields is simple, separate selectors can avoid the wrapper allocation altogether.

QWhat is the type signature of useShallow?

The documented signature is useShallow<T, U = T>(selectorFn: (state: T) => U): (state: T) => U. selectorFn receives current state and returns the data to select; the result is another selector with the same input and output types.

Follow-up: What issue does this address in Zustand v5? A fresh selector result can fail Object.is equality on every update and may trigger an infinite update loop.

  • useStore
  • useBearStore
  • selector
  • Object.is
  • shallow comparison

Source: useShallow - Zustand Docs. Checked 2026-10-15.