1- import { useReducer , useRef , useMemo , useContext , useDebugValue } from 'react'
1+ import { useRef , useMemo , useContext , useDebugValue } from 'react'
2+
3+ import { useSyncExternalStoreExtra } from 'use-sync-external-store/extra'
4+
25import { useReduxContext as useDefaultReduxContext } from './useReduxContext'
36import { createSubscription , Subscription } from '../utils/Subscription'
47import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
@@ -16,94 +19,25 @@ function useSelectorWithStoreAndSubscription<TStoreState, TSelectedState>(
1619 store : Store < TStoreState , AnyAction > ,
1720 contextSub : Subscription
1821) : TSelectedState {
19- const [ , forceRender ] = useReducer ( ( s ) => s + 1 , 0 )
20-
21- const subscription = useMemo (
22- ( ) => createSubscription ( store , contextSub ) ,
23- [ store , contextSub ]
24- )
25-
26- const latestSubscriptionCallbackError = useRef < Error > ( )
27- const latestSelector = useRef < TSelector < TStoreState , TSelectedState > > ( )
28- const latestStoreState = useRef < TStoreState > ( )
29- const latestSelectedState = useRef < TSelectedState > ( )
30-
31- const storeState = store . getState ( )
32- let selectedState : TSelectedState | undefined
33-
34- try {
35- if (
36- selector !== latestSelector . current ||
37- storeState !== latestStoreState . current ||
38- latestSubscriptionCallbackError . current
39- ) {
40- const newSelectedState = selector ( storeState )
41- // ensure latest selected state is reused so that a custom equality function can result in identical references
42- if (
43- latestSelectedState . current === undefined ||
44- ! equalityFn ( newSelectedState , latestSelectedState . current )
45- ) {
46- selectedState = newSelectedState
47- } else {
48- selectedState = latestSelectedState . current
49- }
50- } else {
51- selectedState = latestSelectedState . current
52- }
53- } catch ( err ) {
54- if ( latestSubscriptionCallbackError . current ) {
55- ; (
56- err as Error
57- ) . message += `\nThe error may be correlated with this previous error:\n${ latestSubscriptionCallbackError . current . stack } \n\n`
58- }
59-
60- throw err
61- }
62-
63- useIsomorphicLayoutEffect ( ( ) => {
64- latestSelector . current = selector
65- latestStoreState . current = storeState
66- latestSelectedState . current = selectedState
67- latestSubscriptionCallbackError . current = undefined
68- } )
69-
70- useIsomorphicLayoutEffect ( ( ) => {
71- function checkForUpdates ( ) {
72- try {
73- const newStoreState = store . getState ( )
74- // Avoid calling selector multiple times if the store's state has not changed
75- if ( newStoreState === latestStoreState . current ) {
76- return
77- }
78-
79- const newSelectedState = latestSelector . current ! ( newStoreState )
80-
81- if ( equalityFn ( newSelectedState , latestSelectedState . current ) ) {
82- return
83- }
84-
85- latestSelectedState . current = newSelectedState
86- latestStoreState . current = newStoreState
87- } catch ( err ) {
88- // we ignore all errors here, since when the component
89- // is re-rendered, the selectors are called again, and
90- // will throw again, if neither props nor store state
91- // changed
92- latestSubscriptionCallbackError . current = err as Error
93- }
94-
95- forceRender ( )
22+ const subscribe = useMemo ( ( ) => {
23+ const subscription = createSubscription ( store , contextSub )
24+ const subscribe = ( reactListener : ( ) => void ) => {
25+ // React provides its own subscription handler - trigger that on dispatch
26+ subscription . onStateChange = reactListener
27+ subscription . trySubscribe ( )
28+
29+ return ( ) => subscription . tryUnsubscribe ( )
9630 }
9731
98- subscription . onStateChange = checkForUpdates
99- subscription . trySubscribe ( )
100-
101- checkForUpdates ( )
32+ return subscribe
33+ } , [ store , contextSub ] )
10234
103- return ( ) => subscription . tryUnsubscribe ( )
104- } , [ store , subscription ] )
105-
106- return selectedState !
35+ return useSyncExternalStoreExtra (
36+ subscribe ,
37+ store . getState ,
38+ selector ,
39+ equalityFn
40+ )
10741}
10842
10943/**
0 commit comments