{"record":{"id":"ab9425c4542ae30e","repo":"reduxjs/react-redux","slug":"selector-selector-name-unknown-returned-a","errorCode":null,"errorMessage":"Selector ${selector.name || 'unknown'} returned a different result when called with the same parameters. This can lead to unnecessary rerenders.\nSelectors that return a new reference (such as an object or an array) should be memoized: https://redux.js.org/usage/deriving-data-selectors#optimizing-selectors-with-memoization","messagePattern":"Selector (.+?) returned a different result when called with the same parameters\\. This can lead to unnecessary rerenders\\.\nSelectors that return a new reference \\(such as an object or an array\\) should be memoized: https://redux\\.js\\.org/usage/deriving-data-selectors#optimizing-selectors-with-memoization","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/hooks/useSelector.ts","lineNumber":199,"sourceCode":"            } = {\n              stabilityCheck,\n              identityFunctionCheck,\n              ...devModeChecks,\n            }\n            if (\n              finalStabilityCheck === 'always' ||\n              (finalStabilityCheck === 'once' && firstRun.current)\n            ) {\n              const toCompare = selector(state)\n              if (!equalityFn(selected, toCompare)) {\n                let stack: string | undefined = undefined\n                try {\n                  throw new Error()\n                } catch (e) {\n                  // eslint-disable-next-line no-extra-semi\n                  ;({ stack } = e as Error)\n                }\n                console.warn(\n                  'Selector ' +\n                    (selector.name || 'unknown') +\n                    ' returned a different result when called with the same parameters. This can lead to unnecessary rerenders.' +\n                    '\\nSelectors that return a new reference (such as an object or an array) should be memoized: https://redux.js.org/usage/deriving-data-selectors#optimizing-selectors-with-memoization',\n                  {\n                    state,\n                    selected,\n                    selected2: toCompare,\n                    stack,\n                  },\n                )\n              }\n            }\n            if (\n              finalIdentityFunctionCheck === 'always' ||\n              (finalIdentityFunctionCheck === 'once' && firstRun.current)\n            ) {\n              // @ts-ignore","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/reduxjs/react-redux/blob/16f1a91eb2cc3817bf63753e8c90e528a9f0580c/src/hooks/useSelector.ts#L181-L217","documentation":"In development, react-redux's useSelector re-runs the selector with the last state/args and compares results to detect unstable selectors. This warning fires when a selector called with identical parameters returns a new reference (e.g. a fresh object or array) each call, which defeats reference-equality memoization in useSelector and causes unnecessary component re-renders on every store change.","triggerScenarios":"A selector passed to useSelector returns a newly created object/array (e.g. state => ({a: state.a, b: state.b}) or state => state.items.filter(...)) with no memoization; useSelector with equalityFn left as default reference equality; selector depends on non-memoized derived data.","commonSituations":"Inline arrow selectors in useSelector building result objects; selectors using .map/.filter/.slice returning new arrays; upgrading react-redux (5.x era connect-style selectors moving to hooks) and hitting the new dev-time stability check; forgetting reselect's createSelector or shallowEqual.","solutions":["Memoize the selector with reselect: const selectItems = createSelector([s => s.items], items => items.filter(i => i.done)) and pass that to useSelector.","Return atomic/state slices directly instead of constructing new objects when possible.","If the result is genuinely a new composite, pass an equality function: useSelector(selectResult, shallowEqual) (from react-redux or the shallowequal package).","Keep expensive transformations (filter/map/sort) inside a memoized selector, not inline in useSelector unless inputs are stable.","Only compute derived data via useSelector's memoized arguments pattern if using useReducer-style memoization is not enough — prefer createSelector."],"exampleFix":"// before\nconst { a, b } = useSelector(state => ({ a: state.a, b: state.b }))\n\n// after\nimport { createSelector } from 'reselect'\nimport { shallowEqual } from 'react-redux'\nconst selectAB = createSelector([s => s.a, s => s.b], (a, b) => ({ a, b }))\nconst { a, b } = useSelector(selectAB)\n// or: useSelector(state => ({ a: state.a, b: state.b }), shallowEqual)","handlingStrategy":"validation","validationCode":"// Verify selector stability before wiring it up\nfunction isStableSelector(selector, state, args) {\n  const a = selector(state, args)\n  const b = selector(state, args)\n  return a === b\n}\n// usage: if (!isStableSelector(selectVisibleItems, store.getState())) wrap in createSelector()","typeGuard":null,"tryCatchPattern":"null","preventionTips":["Never build objects/arrays inline in useSelector without shallowEqual or reselect createSelector.","Memoize derived selectors with createSelector and keep them outside components (module scope).","Enable React StrictMode/react-redux dev warnings in CI and treat this console.warn as a failure (assert no console.warn in selector tests).","Use createSelectorCreator with equalityCheck if non-reference equality is intended, or pass shallowEqual to useSelector.","Keep filters/maps/sorts inside memoized selectors, not in render body or inline arrows."],"tags":["react-redux","redux","useselector","memoization","performance","reselect"],"backgroundTag":"unmemoized-selector-new-reference","analyzedSha":"16f1a91eb2cc3817bf63753e8c90e528a9f0580c","analyzedAt":"2026-08-31T22:28:37.628Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}