reduxjs/react-redux · error

You must pass a function as a selector to useSelector

Error message

You must pass a function as a selector to useSelector

What it means

Besides being truthy, the first argument to useSelector must be a function. Development builds throw this when a non-function truthy value (object, string, number) is passed as the selector.

Source

Thrown at src/hooks/useSelector.ts:153

      ? useDefaultReduxContext
      : createReduxContextHook(context)

  const useSelector = <TState, Selected>(
    selector: (state: TState) => Selected,
    equalityFnOrOptions:
      | EqualityFn<NoInfer<Selected>>
      | UseSelectorOptions<NoInfer<Selected>> = {},
  ): Selected => {
    const { equalityFn = refEquality } =
      typeof equalityFnOrOptions === 'function'
        ? { equalityFn: equalityFnOrOptions }
        : equalityFnOrOptions
    if (process.env.NODE_ENV !== 'production') {
      if (!selector) {
        throw new Error(`You must pass a selector to useSelector`)
      }
      if (typeof selector !== 'function') {
        throw new Error(`You must pass a function as a selector to useSelector`)
      }
      if (typeof equalityFn !== 'function') {
        throw new Error(
          `You must pass a function as an equality function to useSelector`,
        )
      }
    }

    const reduxContext = useReduxContext()

    const { store, subscription, getServerState } = reduxContext

    const firstRun = React.useRef(true)

    const wrappedSelector = React.useCallback<typeof selector>(
      {
        [selector.name](state: TState) {
          const selected = selector(state)

View on GitHub (pinned to 16f1a91eb2)

Solutions

  1. Move options to the second argument: useSelector(mySelector, { equalityFn: shallowEqual })
  2. Pass the selector function itself, not its output
  3. Ensure any HOC/wrapper around the selector actually returns a function

Example fix

// before
const value = useSelector({ equalityFn: shallowEqual })
// after
const value = useSelector(state => state.items, { equalityFn: shallowEqual })
Defensive patterns

Strategy: type-guard

Validate before calling

if (process.env.NODE_ENV !== 'production' && typeof mySelector !== 'function') {
  throw new TypeError(`useSelector expects a function, got ${typeof mySelector}`)
}

Type guard

function isUseSelectorCall(fn: unknown, opts?: unknown): boolean {
  return typeof fn === 'function' && (opts === undefined || typeof opts === 'function' || (typeof opts === 'object' && opts !== null));
}

Prevention

When it happens

Trigger: useSelector(someObject) — e.g. passing a state slice or an options object as the first argument instead of the second, or passing an incorrectly memoized value instead of a selector function.

Common situations: Argument order mistakes when adopting the newer useSelector(fn, { equalityFn }) options signature, passing a reselect selector's result rather than the selector itself, or passing a class instance.

Related errors


AI-assisted analysis of reduxjs/react-redux@16f1a91eb2 (2026-08-31). Data as JSON: /api/errors/afeb4224217d1b45. Report an issue: GitHub.