core-native
Version:
A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.
55 lines (48 loc) • 2.29 kB
text/typescript
import React from "react";
import {Action, State} from "./reducer";
import {useDispatch, useSelector} from "react-redux";
type DeferLiteralArrayCheck<T> = T extends Array<string | number | boolean | null | undefined> ? 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<P extends Array<string | number | boolean | null | undefined>>(actionCreator: (...args: P) => Action<P>, ...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<P extends any[], U>(actionCreator: (...args: [...P, U]) => Action<[...DeferLiteralArrayCheck<P>, 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<P extends any[], U, K>(actionCreator: (...args: [...P, U, K]) => Action<[...DeferLiteralArrayCheck<P>, 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<T extends object, K extends keyof T>(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]);
}