Skip to content

Commit

Permalink
apply the same technique in reduxjs#1509
Browse files Browse the repository at this point in the history
  • Loading branch information
dai-shi committed Jan 27, 2020
1 parent 58f69ad commit b68e5eb
Showing 1 changed file with 30 additions and 12 deletions.
42 changes: 30 additions & 12 deletions src/hooks/useSelector.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useReducer, useMemo, useContext } from 'react'
import { useReducer, useEffect, useMemo, useContext } from 'react'
import { useReduxContext as useDefaultReduxContext } from './useReduxContext'
import Subscription from '../utils/Subscription'
import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
import { ReactReduxContext } from '../components/Context'

const refEquality = (a, b) => a === b
Expand All @@ -12,32 +11,51 @@ function useSelectorWithStoreAndSubscription(
store,
contextSub
) {
const [selectedState, checkForUpdates] = useReducer(
prevSelectedState => {
const nextState = store.getState()
const nextSelectedState = selector(nextState)
if (equalityFn(prevSelectedState, nextSelectedState)) {
return prevSelectedState
const [state, dispatch] = useReducer(
(prevState, storeState) => {
const nextSelectedState = selector(storeState)
if (equalityFn(nextSelectedState, prevState.selectedState)) {
// bail out
return prevState
}
return {
selector,
storeState,
selectedState: nextSelectedState
}
return nextSelectedState
},
store.getState(),
selector
storeState => ({
selector,
storeState,
selectedState: selector(storeState)
})
)

let selectedState = state.selectedState
if (state.selector !== selector) {
const nextSelectedState = selector(state.storeState)
if (!equalityFn(nextSelectedState, state.selectedState)) {
selectedState = nextSelectedState
// schedule another update
dispatch(state.storeState)
}
}

const subscription = useMemo(() => new Subscription(store, contextSub), [
store,
contextSub
])

useIsomorphicLayoutEffect(() => {
useEffect(() => {
const checkForUpdates = () => dispatch(store.getState())
subscription.onStateChange = checkForUpdates
subscription.trySubscribe()

checkForUpdates()

return () => subscription.tryUnsubscribe()
}, [subscription])
}, [store, subscription])

return selectedState
}
Expand Down

0 comments on commit b68e5eb

Please sign in to comment.