1- import { useEffect , useReducer , useMemo } from 'react' ;
1+ import {
2+ useEffect , useReducer , useMemo , useRef ,
3+ } from 'react' ;
24
35// useFluxStore essentially combines useReducer and useEffect to use with FluxStores
46// useReducer: Used to extract relevant values from the store
57// useEffect is used to attach a listener to the store
68
79export function useFluxStore ( store , reducer , deps = [ ] ) {
8- // Call useReducer and set initial value from current state of store.
10+ // Use a ref to calculate reducer's initial value from current state of store.
11+ const initReducer = useRef ( ) ;
912
10- // We need to pass reducer(null, store) as initialArg otherwise the first out will be undefined
11- const [ out , _dispatch ] = useReducer ( reducer , reducer ( null , store ) ) ;
13+ if ( ! initReducer . current ) {
14+ initReducer . current = reducer ( null , store ) ;
15+ }
16+
17+ // We need to pass an initialArg otherwise the first *out* will be undefined
18+ const [ out , _dispatch ] = useReducer ( reducer , initReducer . current ) ;
1219
1320 // For any dependencies in the reducer, we make sure to trigger the reducer again
14- useMemo ( ( ) => { _dispatch ( store ) ; } , deps ) ;
21+ useMemo ( ( ) => _dispatch ( store ) , deps ) ; // eslint-disable-line react-hooks/exhaustive-deps
1522
1623 useEffect ( ( ) => {
1724 function listener ( ) {
@@ -28,8 +35,8 @@ export function useFluxStore(store, reducer, deps = []) {
2835
2936 // On useEffect destruction, remove the listener
3037 return ( ) => token . remove ( ) ;
31- } ,
32- [ ] ) ; // We make sure to pass [] so we're not attaching/detaching on every render
38+ } , [ ] ) ; // eslint-disable-line react-hooks/exhaustive-deps
39+ // We make sure to pass [] so we're not attaching/detaching on every render
3340 return out ; // Reducer value gets returned to useFluxStore
3441}
3542
0 commit comments