react-use/src/useStateValidator.ts
xobotyi 436c210f7b
feat(useStateValidator): Refactor method and improve typings;
feat(useMultiStateValidator): Refactor method and improve typings;
2019-11-14 14:40:01 +03:00

40 lines
1.1 KiB
TypeScript

import { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react';
export type ValidityState = [boolean | undefined, ...any[]];
export interface StateValidator<V, S> {
(state: S): V;
(state: S, dispatch: Dispatch<SetStateAction<V>>): void;
}
export type UseStateValidatorReturn<V> = [V, () => void];
export default function useStateValidator<V extends ValidityState, S, I extends V>(
state: S,
validator: StateValidator<V, S>,
initialState: I = [undefined] as I
): UseStateValidatorReturn<V> {
const validatorInner = useRef(validator);
const stateInner = useRef(state);
validatorInner.current = validator;
stateInner.current = state;
const [validity, setValidity] = useState(initialState as V);
const validate = useCallback(() => {
if (validatorInner.current.length >= 2) {
validatorInner.current(stateInner.current, setValidity as Dispatch<SetStateAction<V>>);
} else {
setValidity(validatorInner.current(stateInner.current));
}
}, [setValidity]);
useEffect(() => {
validate();
}, [state]);
return [validity, validate];
}