Created
March 14, 2020 04:07
-
-
Save haishanh/f9ac060ac5fdc6fb734f4aebe76c2a1a to your computer and use it in GitHub Desktop.
redux-with-hooks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createStore, applyMiddleware, compose } from 'redux'; | |
import thunkMiddleware from 'redux-thunk'; | |
import rootReducer from '../ducks'; | |
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; | |
function configureStore() { | |
const store = createStore( | |
rootReducer, | |
composeEnhancers(applyMiddleware(thunkMiddleware)) | |
); | |
if (module.hot) { | |
// Enable Webpack hot module replacement for reducers | |
module.hot.accept('../ducks', () => { | |
const nextRootReducer = require('../ducks').default; | |
store.replaceReducer(nextRootReducer); | |
}); | |
} | |
// eslint-disable-next-line no-undef | |
if (__DEV__) { | |
window.getState = store.getState; | |
} | |
return store; | |
} | |
const store = configureStore(); | |
export { store }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const hasOwn = Object.prototype.hasOwnProperty; | |
function is(x, y) { | |
if (x === y) { | |
return x !== 0 || y !== 0 || 1 / x === 1 / y; | |
} else { | |
// eslint-disable-next-line no-self-compare | |
return x !== x && y !== y; | |
} | |
} | |
export default function shallowEqual(objA, objB) { | |
if (is(objA, objB)) return true; | |
if ( | |
typeof objA !== 'object' || | |
objA === null || | |
typeof objB !== 'object' || | |
objB === null | |
) { | |
return false; | |
} | |
const keysA = Object.keys(objA); | |
const keysB = Object.keys(objB); | |
if (keysA.length !== keysB.length) return false; | |
for (let i = 0; i < keysA.length; i++) { | |
if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { | |
return false; | |
} | |
} | |
return true; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment