Skip to content

Instantly share code, notes, and snippets.

@Freak613
Created February 11, 2020 09:11
Show Gist options
  • Save Freak613/b5924224b9db703e9ed06fcd6ee72089 to your computer and use it in GitHub Desktop.
Save Freak613/b5924224b9db703e9ed06fcd6ee72089 to your computer and use it in GitHub Desktop.
// Fork of https://github.com/shiningjason/react-enhanced-reducer-hook/blob/master/index.js
const useHandler = fn => {
const ref = useRef({
fn,
handler: (...args) => ref.current.fn(...args)
});
ref.current.fn = fn;
return ref.current.handler;
};
const compose = (...fns) => {
if (fns.length === 0) return arg => arg;
if (fns.length === 1) return fns[0];
return fns.reduce((a, b) => (...args) => a(b(...args)));
};
const useEnhancedReducer = (reducer, initialState, middlewares = []) => {
const [error, setError] = useState();
const hook = useState(initialState);
let state = hook[0];
const setState = hook[1];
const dispatch = useHandler(action => {
state = reducer(state, action);
setState(state);
return action;
});
const getState = useHandler(() => state);
const storeDispatch = useHandler((...args) => enhancedDispatch(...args));
const enhancedDispatch = useMemo(() => {
const chain = middlewares.map(middleware =>
middleware({ getState, dispatch: storeDispatch, onError: setError })
);
return compose(...chain)(dispatch);
}, []);
if (error) throw error;
return [state, enhancedDispatch];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment