Skip to content

Commit b68e5eb

Browse files
committed
apply the same technique in reduxjs#1509
1 parent 58f69ad commit b68e5eb

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

src/hooks/useSelector.js

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { useReducer, useMemo, useContext } from 'react'
1+
import { useReducer, useEffect, useMemo, useContext } from 'react'
22
import { useReduxContext as useDefaultReduxContext } from './useReduxContext'
33
import Subscription from '../utils/Subscription'
4-
import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
54
import { ReactReduxContext } from '../components/Context'
65

76
const refEquality = (a, b) => a === b
@@ -12,32 +11,51 @@ function useSelectorWithStoreAndSubscription(
1211
store,
1312
contextSub
1413
) {
15-
const [selectedState, checkForUpdates] = useReducer(
16-
prevSelectedState => {
17-
const nextState = store.getState()
18-
const nextSelectedState = selector(nextState)
19-
if (equalityFn(prevSelectedState, nextSelectedState)) {
20-
return prevSelectedState
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
2125
}
22-
return nextSelectedState
2326
},
2427
store.getState(),
25-
selector
28+
storeState => ({
29+
selector,
30+
storeState,
31+
selectedState: selector(storeState)
32+
})
2633
)
2734

35+
let selectedState = state.selectedState
36+
if (state.selector !== selector) {
37+
const nextSelectedState = selector(state.storeState)
38+
if (!equalityFn(nextSelectedState, state.selectedState)) {
39+
selectedState = nextSelectedState
40+
// schedule another update
41+
dispatch(state.storeState)
42+
}
43+
}
44+
2845
const subscription = useMemo(() => new Subscription(store, contextSub), [
2946
store,
3047
contextSub
3148
])
3249

33-
useIsomorphicLayoutEffect(() => {
50+
useEffect(() => {
51+
const checkForUpdates = () => dispatch(store.getState())
3452
subscription.onStateChange = checkForUpdates
3553
subscription.trySubscribe()
3654

3755
checkForUpdates()
3856

3957
return () => subscription.tryUnsubscribe()
40-
}, [subscription])
58+
}, [store, subscription])
4159

4260
return selectedState
4361
}

0 commit comments

Comments
 (0)