1.0.6 • Published 2 years ago
action-hook v1.0.6
Action Hook Documentation
Use useReducer more efficiently.
Install
$ npm install action-hook
Usage
1. useActions
import { useActions } from 'action-hook';
const initState = { count: 0 };
const reducers = {
add: (state, payload: number) => ({
...state,
count: state.count + payload,
}),
increment: (state) => ({
...state,
count: state.count + 1,
}),
};
const [state, actions] = useActions(reducers, initState);
actions.increment() // state.count: 0 => 1
actions.add(10) // state.count: 1 => 11
2. useLoading
import { useLoading, loadingSelector } from 'action-hook';
const initState = { count: 0 };
const reducers = {
increment: (state) => ({
...state,
count: state.count + 1,
}),
};
const [state, actions] = useLoading(reducers, initState);
actions.loading() // state.loading: 0 => 1
loadingSelector(state) // true
actions.increment() // state.count: 0 => 1
actions.loadingCompleted() // state.loading: 0 => 1
loadingSelector(state) // false
Extend Your Own Action Hooks
You can extend Action Hooks like useLoading hook.
Define initstate and reducers.
// state.ts export interface LoadingStateInterface { loading: number; } export const initialLoadingState: LoadingStateInterface = { loading: 0, };
// reducers.ts import type { LoadingStateInterface } from "./state"; function loading<T extends LoadingStateInterface>(state: T): T { return { ...state, loading: state.loading + 1, }; } function loadingCompleted<T extends LoadingStateInterface>(state: T): T { return { ...state, loading: state.loading - 1, }; } const reducers = { loading, loadingCompleted, }; export default reducers; export type LoadingReducersTypes = typeof reducers;
Extend useActions hook.
// useLoading.ts import useActions, { ReducersInterface, StateAndActionsInterface, merge } from "action-hook"; import { initialLoadingState, LoadingStateInterface } from "./state"; import loadingReducers, { LoadingReducersTypes } from "./reducers"; export { loadingSelector } from "./selector"; type MergeReducers<R> = LoadingReducersTypes & R; type MergeState<S> = LoadingStateInterface & S; type StateActions<S, R> = StateAndActionsInterface< MergeState<S>, MergeReducers<R> >; export default function useLoadingActions<S, R extends ReducersInterface>( reducers?: R, initialState?: S ): StateActions<S, R> { return useActions( merge(loadingReducers, reducers as R), merge(initialLoadingState, initialState as S) ); }
Create
selector.ts
file to handling reading complex state.// selector.ts import type { LoadingStateInterface } from "./state"; export const loadingSelector = (state: LoadingStateInterface) => state.loading > 0;