1
- import { useState , useEffect , useMemo , useContext } from 'react'
1
+ import { useReducer , useEffect , useMemo , useContext } from 'react'
2
2
import { useReduxContext as useDefaultReduxContext } from './useReduxContext'
3
3
import Subscription from '../utils/Subscription'
4
4
import { ReactReduxContext } from '../components/Context'
@@ -11,72 +11,44 @@ function useSelectorWithStoreAndSubscription(
11
11
store ,
12
12
contextSub
13
13
) {
14
- const [ state , setState ] = useState ( ( ) => ( {
15
- storeState : store . getState ( ) ,
16
- selector,
17
- selectedState : selector ( store . getState ( ) )
18
- // subscriptionCallbackError: undefined
19
- } ) )
14
+ const [ state , dispatch ] = useReducer (
15
+ ( prevState , storeState ) => {
16
+ const nextSelectedState = selector ( storeState )
17
+ if ( equalityFn ( nextSelectedState , prevState . selectedState ) ) {
18
+ // bail out
19
+ return prevState
20
+ }
21
+ return {
22
+ selector,
23
+ storeState,
24
+ selectedState : nextSelectedState
25
+ }
26
+ } ,
27
+ store . getState ( ) ,
28
+ storeState => ( {
29
+ selector,
30
+ storeState,
31
+ selectedState : selector ( storeState )
32
+ } )
33
+ )
20
34
21
35
const subscription = useMemo ( ( ) => new Subscription ( store , contextSub ) , [
22
36
store ,
23
37
contextSub
24
38
] )
25
39
26
40
let selectedState = state . selectedState
27
-
28
- try {
29
- if ( selector !== state . selector || state . subscriptionCallbackError ) {
30
- const newSelectedState = selector ( state . storeState )
31
- if ( ! equalityFn ( newSelectedState , selectedState ) ) {
32
- selectedState = newSelectedState
33
- // schedule another update
34
- setState ( prevState => ( {
35
- ...prevState ,
36
- selector,
37
- selectedState
38
- // subscriptionCallbackError: undefined
39
- } ) )
40
- }
41
- }
42
- } catch ( err ) {
43
- if ( state . subscriptionCallbackError ) {
44
- err . message += `\nThe error may be correlated with this previous error:\n${ state . subscriptionCallbackError . stack } \n\n`
41
+ if ( state . selector !== selector ) {
42
+ const nextSelectedState = selector ( state . storeState )
43
+ if ( ! equalityFn ( nextSelectedState , state . selectedState ) ) {
44
+ selectedState = nextSelectedState
45
+ // schedule another update
46
+ dispatch ( state . storeState )
45
47
}
46
-
47
- throw err
48
48
}
49
49
50
50
useEffect ( ( ) => {
51
- function checkForUpdates ( ) {
52
- const newStoreState = store . getState ( )
53
- setState ( prevState => {
54
- let newSelectedState
55
- let subscriptionCallbackError
56
- try {
57
- newSelectedState = prevState . selector ( newStoreState )
58
-
59
- if ( equalityFn ( newSelectedState , prevState . selectedState ) ) {
60
- // bail out rendering
61
- return prevState
62
- }
63
- } catch ( err ) {
64
- // we ignore all errors here, since when the component
65
- // is re-rendered, the selectors are called again, and
66
- // will throw again, if neither props nor store state
67
- // changed
68
- subscriptionCallbackError = err
69
- }
70
-
71
- return {
72
- ...prevState ,
73
- storeState : newStoreState ,
74
- selectedState : newSelectedState ,
75
- subscriptionCallbackError
76
- }
77
- } )
78
- }
79
-
51
+ const checkForUpdates = ( ) => dispatch ( store . getState ( ) )
80
52
subscription . onStateChange = checkForUpdates
81
53
subscription . trySubscribe ( )
82
54
0 commit comments