Extending astx-redux-util
There are many reasons to extend the capabilities of any utility. It may be a specific proprietary requirement or a common cross-cutting concerns such as timing, logging, etc. In either case, extending a collective utility provides value-added semantics that are centrally applied.
The reducer composition utilities promoted by astx-redux-util are higher-order reducers, in that their invocation returns other functions (reducers). Such utilities are typically expanded by wrapping them. In the case of higher-order functions (hof), this includes wrapping both the hof (the creator) and the returned function (the created).
The Extension
The basic template for this process is shown here. We enhance
reducerHash()
, by applying a hypothetical foo operation
...
import AstxReduxUtil from 'astx-redux-util';
// value-added reducerHash.withFoo()
// ... a wrapper applying FOO to reducerHash() - a higher-order function (HOF)
// - WITH an additional parameter:
// * foo: {Foo} fooBar
AstxReduxUtil.reducerHash.withFoo = (foo, ...reducerHashArgs) => {
// invoke the original reducerHash()
const reducerFn = AstxReduxUtil.reducerHash(...reducerHashArgs);
// wrap the resultant reducerFn to apply our value-added FOO
return (...reducerArgs) => {
// NOTE: we have access to foo, reducerHashArgs, and reducerArgs!!!
// ... before logic here (if any)
// invoke the original reducerFn()
const nextState = reducerFn(...reducerArgs);
// ... after logic here (if any)
return nextState;
};
};
The inline comments should be self-explanatory, but here are some high-level points of interest:
The
withFoo()
extension is cataloged on the reducerHash function itself, making it directly available from the 'astx-redux-util' import. You may choose to make this it's own separate module.The foo process requires addition information (i.e. a Foo object) which is passed as a parameter, along with the reducerHash parameters.
The wrapper invokes the underlying reducerHash function, and in turn, wraps the created reducer function.
The reducer wrapper is where the real enhancement is implemented.
We ultimately invoke the original reducerFn(), but have the opportunity to both pre and post process this invocation, with what ever logic we wish.
Our wrapper has access to the new foo parameter, in addition to the standard parameters of this utility (both reducerHashArgs and reducerArgs).
Usage
From a usage perspective, we simply replace
reducerHash()
invocations with reducerHash.withFoo()
and
pass the appropriate foo parameter in addition to the reducerHash
arguments.
import { reducerHash } from 'astx-redux-util';
const foo = ...;
export default reducerHash.withFoo(foo, {
"widget.edit": (widget, action) => action.widget,
"widget.edit.close": (widget, action) => null,
}, null);