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 | }
|
---|