[d24f17c] | 1 | import type { AnyFunction } from '../types'
|
---|
| 2 |
|
---|
| 3 | /**
|
---|
| 4 | * Runs a check to determine if the given result function behaves as an
|
---|
| 5 | * identity function. An identity function is one that returns its
|
---|
| 6 | * input unchanged, for example, `x => x`. This check helps ensure
|
---|
| 7 | * efficient memoization and prevent unnecessary re-renders by encouraging
|
---|
| 8 | * proper use of transformation logic in result functions and
|
---|
| 9 | * extraction logic in input selectors.
|
---|
| 10 | *
|
---|
| 11 | * @param resultFunc - The result function to be checked.
|
---|
| 12 | * @param inputSelectorsResults - The results of the input selectors.
|
---|
| 13 | * @param outputSelectorResult - The result of the output selector.
|
---|
| 14 | *
|
---|
| 15 | * @see {@link https://reselect.js.org/api/development-only-stability-checks#identityfunctioncheck `identityFunctionCheck`}
|
---|
| 16 | *
|
---|
| 17 | * @since 5.0.0
|
---|
| 18 | * @internal
|
---|
| 19 | */
|
---|
| 20 | export const runIdentityFunctionCheck = (
|
---|
| 21 | resultFunc: AnyFunction,
|
---|
| 22 | inputSelectorsResults: unknown[],
|
---|
| 23 | outputSelectorResult: unknown
|
---|
| 24 | ) => {
|
---|
| 25 | if (
|
---|
| 26 | inputSelectorsResults.length === 1 &&
|
---|
| 27 | inputSelectorsResults[0] === outputSelectorResult
|
---|
| 28 | ) {
|
---|
| 29 | let isInputSameAsOutput = false
|
---|
| 30 | try {
|
---|
| 31 | const emptyObject = {}
|
---|
| 32 | if (resultFunc(emptyObject) === emptyObject) isInputSameAsOutput = true
|
---|
| 33 | } catch {
|
---|
| 34 | // Do nothing
|
---|
| 35 | }
|
---|
| 36 | if (isInputSameAsOutput) {
|
---|
| 37 | let stack: string | undefined = undefined
|
---|
| 38 | try {
|
---|
| 39 | throw new Error()
|
---|
| 40 | } catch (e) {
|
---|
| 41 | // eslint-disable-next-line @typescript-eslint/no-extra-semi, no-extra-semi
|
---|
| 42 | ;({ stack } = e as Error)
|
---|
| 43 | }
|
---|
| 44 | console.warn(
|
---|
| 45 | 'The result function returned its own inputs without modification. e.g' +
|
---|
| 46 | '\n`createSelector([state => state.todos], todos => todos)`' +
|
---|
| 47 | '\nThis could lead to inefficient memoization and unnecessary re-renders.' +
|
---|
| 48 | '\nEnsure transformation logic is in the result function, and extraction logic is in the input selectors.',
|
---|
| 49 | { stack }
|
---|
| 50 | )
|
---|
| 51 | }
|
---|
| 52 | }
|
---|
| 53 | }
|
---|