reduxjs/react-redux · warning

Selector ${selector.name || 'unknown'} returned the root sta

Error message

Selector ${selector.name || 'unknown'} returned the root state when called. This can lead to unnecessary rerenders.
Selectors that return the entire state are almost certainly a mistake, as they will cause a rerender whenever *anything* in state changes.

What it means

useSelector runs a dev-mode check that warns when a selector returns the entire state object (result === state). Returning the root state means the subscribed component re-renders whenever ANY part of the store changes, since the root state reference changes on every dispatched action. The library flags it because returning the whole state from a selector is almost always an accidental mistake.

Source

Thrown at src/hooks/useSelector.ts:226

                    stack,
                  },
                )
              }
            }
            if (
              finalIdentityFunctionCheck === 'always' ||
              (finalIdentityFunctionCheck === 'once' && firstRun.current)
            ) {
              // @ts-ignore
              if (selected === state) {
                let stack: string | undefined = undefined
                try {
                  throw new Error()
                } catch (e) {
                  // eslint-disable-next-line no-extra-semi
                  ;({ stack } = e as Error)
                }
                console.warn(
                  'Selector ' +
                    (selector.name || 'unknown') +
                    ' returned the root state when called. This can lead to unnecessary rerenders.' +
                    '\nSelectors that return the entire state are almost certainly a mistake, as they will cause a rerender whenever *anything* in state changes.',
                  { stack },
                )
              }
            }
            if (firstRun.current) firstRun.current = false
          }
          return selected
        },
      }[selector.name],
      [selector],
    )

    const selectedState = useSyncExternalStoreWithSelector(
      subscription.addNestedSub,

View on GitHub (pinned to 16f1a91eb2)

Solutions

  1. Select the narrowest slice needed: useSelector(state => state.users) instead of useSelector(state => state).
  2. Split data needs into multiple useSelector calls per slice/field.
  3. If truly whole-state access is needed (rare), accept the re-render cost or subscribe via useStore + manual logic instead.
  4. Double-check the function passed to useSelector actually selects — it must take state and return derived data, not the store or state itself.
  5. Use typed hooks (TypedUseSelectorHook<RootState>) so mistakes like returning state are visible in review.

Example fix

// before
const state = useSelector(state => state)
const user = state.user

// after
const user = useSelector(state => state.user)
// or for multiple slices:
const user = useSelector(state => state.user)
const items = useSelector(state => state.items)
Defensive patterns

Strategy: validation

Validate before calling

// Assert a selector never returns the root state
function assertNotRootState(selector, state) {
  const result = selector(state)
  if (result === state) {
    throw new Error(`${selector.name || 'unknown'} returns the root state; select a narrower slice instead`)
  }
  return selector
}
// usage: const safeSelector = assertNotRootState(mySelector, store.getState())

Try / catch

null

Prevention

When it happens

Trigger: Passing an identity-ish selector such as useSelector(state => state) or useSelector(state => ({...state})) effectively; using a selector that ignores its argument and returns the store/state; accidentally passing a non-selector (e.g. the store itself or a mis-bound function) to useSelector.

Common situations: Copy-pasted hook code where the selector body was deleted leaving state => state; new developers grabbing "all data" to destructure later; TypeScript mistakes where a generic selector defaults to RootState; refactoring where the intended slice selector was replaced by the state parameter itself.

Related errors


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