Skip to content

Instantly share code, notes, and snippets.

@staydecent
Created September 12, 2019 19:35
Show Gist options
  • Save staydecent/7785dc6751ab1fe5f4536153dfffc192 to your computer and use it in GitHub Desktop.
Save staydecent/7785dc6751ab1fe5f4536153dfffc192 to your computer and use it in GitHub Desktop.
useMappedState
import { useEffect, useReducer, useRef } from 'react' // alias to 'preact/hooks'
import equal from '@app-elements/equal'
export function useMappedState (store, mapper) {
const [, forceRender] = useReducer(n => n + 1, 0)
const mapperRef = useRef()
const stateRef = useRef()
let mappedState = mapper !== mapperRef.current
? mapper(store.getState())
: stateRef.current
useEffect(() => {
mapperRef.current = mapper
stateRef.current = mappedState
})
useEffect(() => {
function handleStateChange () {
const newSelectedState = mapperRef.current(store.getState())
if (!equal(newSelectedState, stateRef.current)) {
stateRef.current = newSelectedState
forceRender({})
}
}
const unsubscribe = store.subscribe(handleStateChange)
handleStateChange()
return () => unsubscribe()
}, [store, mapper])
return mappedState
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment