feat: improve createReducer function

enhance #164  createReducer
This commit is contained in:
Va Da 2019-05-24 20:46:21 +02:00 committed by GitHub
commit 6ba2d93700
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,35 +1,36 @@
import { useReducer } from 'react';
import { useMemo, useRef, useState } from 'react';
function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)));
function composeMiddleware(chain) {
return (context, dispatch) => {
return chain.reduceRight((res, middleware) => {
return middleware(context)(res);
}, dispatch);
};
}
const createReducer = (...middlewares) => (...args) => {
const [state, dispatch] = useReducer(...args);
const createReducer = (...middlewares) => (reducer, initialState, initializer = value => value) => {
const ref = useRef(initializer(initialState))
const [, setState] = useState(ref.current)
let middlewareDispatch = () => {
throw new Error(
'Dispatching while constructing your middleware is not allowed. ' +
'Other middleware would not be applied to this dispatch.'
);
};
const dispatch = action => {
ref.current = reducer(ref.current, action)
setState(ref.current)
return action;
}
const composedMiddleware = useMemo(() => {
return composeMiddleware(middlewares);
}, middlewares);
const middlewareAPI = {
getState: () => state,
getState: () => ref.current,
dispatch: (...args) => middlewareDispatch(...args),
};
const chain = middlewares.map(middleware => middleware(middlewareAPI));
middlewareDispatch = compose(...chain)(dispatch);
return [state, middlewareDispatch];
middlewareDispatch = composedMiddleware(middlewareAPI, dispatch);
return [ref.current, middlewareDispatch];
};
export default createReducer;