import createState from "state-modules";
createState(config: StateManagerConfig): StateManager
type StateManagerConfig = {|
+config: {|
+mid: StateModuleID
|},
hooks?: {|
before?: Iterable<BeforeHookFunction>,
change?: Iterable<StateChangeHookFunction>,
after?: Iterable<AfterHookFunction>,
error?: Iterable<ErrorHookFunction>
|}
|};
{
// required configuration with a given "module id"
config: { mid: 'my-module' },
// Hooks allow simple hooking into the lifecycle of the state
hooks: {
// Before action is dispatched, may return an action with new properties
before: [action => console.group('DISPATCHING: ', action)],
// Whenever the state changes, gets previous and next as well as an object
// with only the changed values.
change: [(action, prevState, changedValues) => console.log('State Changed: ', changedValues)],
// After the dispatch has occurred.
after: [() => console.groupEnd()],
// Any error that occurs within the realm of the dispatch
error: [e => console.error('Error: ', e)],
},
}
Before hooks are executed before a dispatched actions is handled by the StateManager
. It allows controlling of the flow of the module as a whole in a few different ways:
- If a hook returns a
null
value, the dispatch will be cancelled. - If an
object
is returned, it will dispatch the new object instead. - If it
undefined
is returned, the original action will be dispatched.
type BeforeHookFunction = (
action: StateDispatchedAction
) => action | null | void;
Change hooks are executed only when the state has been changed in some way.
type ChangeHookFunction = (
action: StateDispatchedAction,
prevState: State,
changedValues: Array<StatePath>
) => any;
After hooks are executed after the dispatch has been processed and the state reducers have been called. There is no guarantee that the state effects have been completely resolved at this point.
type AfterHookFunction = (
action: StateDispatchedAction,
prevState: State,
changedValues: Array<StatePath>
) => any;
Error hooks are executed if an error occurs during the processing of a dispatch.
type ErrorHookFunction = (
action: StateDispatchedAction,
error: Error
) => any;
interface StateManager {
mid: string;
get components(): Array<State$ComponentID>;
get actions(): StateActionDispatchers;
get context(): State$Context
select<R>(selector: string | string[] | (state: State) => R): R
component(...components: Array<State$ComponentConfig>): State$Manager;
dispatch(action: State$DispatchedAction): Promise<void | State$ChangedPaths>;
subscribe<TO>(to: TO, condition: State$Condition<TO>, once?: boolean): State$Subscription;
connect(
withState: StateConnectState,
withDispatchers: StateConnectDispatchers
): (component: React.Component<*>) => React.Component<*>;
resolve(): Promise<void>
}
type StateComponentConfig = {
config: {|
cid: State$ComponentID,
prefix?: string,
loadsOnAction?: State$ActionSelector,
scopeID?: string
|},
scope?: () => Promise<State$ComponentScope>,
state?: State$StateFragment,
actions?: State$ActionCreators,
reducers?: State$Reducers,
routes?: State$EffectRoutes,
effects?: State$Effects,
selectors?: State$Selectors,
hooks?: State$ComponentHooks
};