1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
import React, {
createContext,
useState,
useEffect,
useContext,
useMemo
} from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import shallowEqual from './shallowEqual';
const StoreContext = createContext(null);
export function Provider({ store, children }) {
return (
<StoreContext.Provider value={store}>{children}</StoreContext.Provider>
);
}
Provider.propTypes = {
store: PropTypes.object,
children: PropTypes.node
};
export function useStore() {
// return the context
// which is the redux store
return useContext(StoreContext);
}
function bindActions(actions, dispatch) {
const a = typeof actions === 'function' ? actions() : actions;
return bindActionCreators(a, dispatch);
}
export function useActions(actions) {
const { dispatch } = useStore();
return useMemo(() => bindActions(actions, dispatch), [actions, dispatch]);
}
export function useStoreState(selector) {
const store = useStore();
const initialMappedState = selector(store.getState());
const [compState, setCompState] = useState(initialMappedState);
// subscribe to store change
useEffect(() => {
let compStateCurr = compState;
return store.subscribe(() => {
const compStateNext = selector(store.getState());
if (shallowEqual(compStateCurr, compStateNext)) return;
// update state if not equal
compStateCurr = compStateNext;
setCompState(compStateNext);
});
}, [compState, selector, store]);
return compState;
}
|