@@ -3,15 +3,6 @@ import * as React from 'react';
3
3
4
4
import { Context , ContextSelector , ContextValue , ContextVersion } from './types' ;
5
5
6
- /**
7
- * Narrowing React.Reducer type to be more easily usable below.
8
- * No need to export this as it's for internal reducer usage.
9
- */
10
- type ContextReducer < Value , SelectedValue > = React . Reducer <
11
- readonly [ Value , SelectedValue ] ,
12
- undefined | readonly [ ContextVersion , Value ]
13
- > ;
14
-
15
6
/**
16
7
* @internal
17
8
* This hook returns context selected value by selector.
@@ -31,49 +22,51 @@ export const useContextSelector = <Value, SelectedValue>(
31
22
} = contextValue ;
32
23
const selected = selector ( value ) ;
33
24
34
- const [ state , dispatch ] = React . useReducer < ContextReducer < Value , SelectedValue > > (
25
+ const [ state , setState ] = React . useState < readonly [ Value , SelectedValue ] > ( [ value , selected ] ) ;
26
+ const dispatch = React . useCallback (
35
27
(
36
- prevState : readonly [ Value /* contextValue */ , SelectedValue /* selector(value) */ ] ,
37
28
payload :
38
29
| undefined // undefined from render below
39
30
| readonly [ ContextVersion , Value ] , // from provider effect
40
- ) : readonly [ Value , SelectedValue ] => {
41
- if ( ! payload ) {
42
- // early bail out when is dispatched during render
43
- return [ value , selected ] as const ;
44
- }
45
-
46
- if ( payload [ 0 ] <= version ) {
47
- if ( objectIs ( prevState [ 1 ] , selected ) ) {
48
- return prevState ; // bail out
31
+ ) => {
32
+ setState ( prevState => {
33
+ if ( ! payload ) {
34
+ // early bail out when is dispatched during render
35
+ return [ value , selected ] as const ;
49
36
}
50
37
51
- return [ value , selected ] as const ;
52
- }
38
+ if ( payload [ 0 ] <= version ) {
39
+ if ( Object . is ( prevState [ 1 ] , selected ) ) {
40
+ return prevState ; // bail out
41
+ }
53
42
54
- try {
55
- if ( objectIs ( prevState [ 0 ] , payload [ 1 ] ) ) {
56
- return prevState ; // do not update
43
+ return [ value , selected ] as const ;
57
44
}
58
45
59
- const nextSelected = selector ( payload [ 1 ] ) ;
46
+ try {
47
+ if ( Object . is ( prevState [ 0 ] , payload [ 1 ] ) ) {
48
+ return prevState ; // do not update
49
+ }
60
50
61
- if ( objectIs ( prevState [ 1 ] , nextSelected ) ) {
62
- return prevState ; // do not update
63
- }
51
+ const nextSelected = selector ( payload [ 1 ] ) ;
52
+
53
+ if ( Object . is ( prevState [ 1 ] , nextSelected ) ) {
54
+ return prevState ; // do not update
55
+ }
64
56
65
- return [ payload [ 1 ] , nextSelected ] as const ;
66
- } catch ( e ) {
67
- // ignored (stale props or some other reason)
68
- }
57
+ return [ payload [ 1 ] , nextSelected ] as const ;
58
+ } catch ( e ) {
59
+ // ignored (stale props or some other reason)
60
+ }
69
61
70
- // explicitly spread to enforce typing
71
- return [ prevState [ 0 ] , prevState [ 1 ] ] as const ; // schedule update
62
+ // explicitly spread to enforce typing
63
+ return [ prevState [ 0 ] , prevState [ 1 ] ] as const ; // schedule update
64
+ } ) ;
72
65
} ,
73
- [ value , selected ] as const ,
66
+ [ ] ,
74
67
) ;
75
68
76
- if ( ! objectIs ( state [ 1 ] , selected ) ) {
69
+ if ( ! Object . is ( state [ 1 ] , selected ) ) {
77
70
// schedule re-render
78
71
// this is safe because it's self contained
79
72
dispatch ( undefined ) ;
@@ -90,20 +83,3 @@ export const useContextSelector = <Value, SelectedValue>(
90
83
91
84
return state [ 1 ] as SelectedValue ;
92
85
} ;
93
-
94
- /**
95
- * inlined Object.is polyfill to avoid requiring consumers ship their own
96
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
97
- */
98
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
- function is ( x : any , y : any ) {
100
- return (
101
- ( x === y && ( x !== 0 || 1 / x === 1 / y ) ) || ( x !== x && y !== y ) // eslint-disable-line no-self-compare
102
- ) ;
103
- }
104
-
105
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
106
- const objectIs : ( x : any , y : any ) => boolean =
107
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
108
- // @ts -ignore fallback to native if it exists (not in IE11)
109
- typeof Object . is === 'function' ? Object . is : is ;
0 commit comments