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
- Select the narrowest slice needed: useSelector(state => state.users) instead of useSelector(state => state).
- Split data needs into multiple useSelector calls per slice/field.
- If truly whole-state access is needed (rare), accept the re-render cost or subscribe via useStore + manual logic instead.
- Double-check the function passed to useSelector actually selects — it must take state and return derived data, not the store or state itself.
- 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
- Select the smallest slice each component needs; one useSelector per slice.
- Never write useSelector(state => state); destructure at store level only in tests/debug tools.
- Use typed hooks (TypedUseSelectorHook<RootState>) to keep selector return types explicit and reviewable.
- In CI, assert no console.warn about root-state selectors during component tests.
- If whole-state reactivity is intentional, document it and bypass useSelector (useStore + subscription) to make the choice explicit.
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
- Selector ${selector.name || 'unknown'} returned a different
- You must pass a selector to useSelector
- You must pass a function as a selector to useSelector
- You must pass a function as an equality function to useSelec
- Could not find "store" in the context of "${displayName}". E
AI-assisted analysis of reduxjs/react-redux@16f1a91eb2 (2026-08-31).
Data as JSON: /api/errors/48fd2823163821f8.
Report an issue: GitHub.