import React from "react"; import {useDispatch, useSelector} from "react-redux"; import {type Action, type State} from "./reducer"; type DeferLiteralArrayCheck = T extends Array ? T : never; export function useLoadingStatus(identifier: string = "global"): boolean { return useSelector((state: State) => state.loading[identifier] > 0); } /** * Action parameters must be of primitive types, so that the dependency check can work well. * No need add dispatch to dep list, because it is always fixed. */ export function useAction

>(actionCreator: (...args: P) => Action

, ...deps: P): () => void { const dispatch = useDispatch(); return React.useCallback(() => dispatch(actionCreator(...deps)), deps); } /** * For actions like: * *foo(a: number, b: string, c: boolean): SagaGenerator {..} * * useUnaryAction(foo, 100, "") will return: * (c: boolean) => void; */ export function useUnaryAction

(actionCreator: (...args: [...P, U]) => Action<[...DeferLiteralArrayCheck

, U]>, ...deps: P): (arg: U) => void { const dispatch = useDispatch(); return React.useCallback((arg: U) => dispatch(actionCreator(...deps, arg)), deps); } /** * For actions like: * *foo(a: number, b: string, c: boolean): SagaGenerator {..} * * useBinaryAction(foo, 100) will return: * (b: string, c: boolean) => void; */ export function useBinaryAction

(actionCreator: (...args: [...P, U, K]) => Action<[...DeferLiteralArrayCheck

, U, K]>, ...deps: P): (arg1: U, arg2: K) => void { const dispatch = useDispatch(); return React.useCallback((arg1: U, arg2: K) => dispatch(actionCreator(...deps, arg1, arg2)), deps); } /** * For actions like: * *foo(data: {key: number}): SagaGenerator {..} * * useModuleObjectAction(foo, "key") will return: * (objectValue: number) => void; */ export function useObjectKeyAction(actionCreator: (arg: T) => Action<[T]>, objectKey: K): (objectValue: T[K]) => void { const dispatch = useDispatch(); return React.useCallback((objectValue: T[K]) => dispatch(actionCreator({[objectKey]: objectValue} as T)), [dispatch, actionCreator, objectKey]); }