react-use/src/useMultiStateValidator.ts
xobotyi b6993a6f95
feat(prettier): make prettier a part of eslint.
Also reduce max line width to 100. And remove `lint:types` step for
commit sequence, it bothers when committing incomplete (wip) changes.
2021-02-01 18:58:55 +03:00

44 lines
1.3 KiB
TypeScript

import { useCallback, useEffect, useRef, useState } from 'react';
import { StateValidator, UseStateValidatorReturn, ValidityState } from './useStateValidator';
export type MultiStateValidatorStates = any[] | { [p: string]: any } | { [p: number]: any };
export type MultiStateValidator<
V extends ValidityState,
S extends MultiStateValidatorStates
> = StateValidator<V, S>;
export function useMultiStateValidator<
V extends ValidityState,
S extends MultiStateValidatorStates
>(
states: S,
validator: MultiStateValidator<V, S>,
initialValidity: V = [undefined] as V
): UseStateValidatorReturn<V> {
if (typeof states !== 'object') {
throw new Error('states expected to be an object or array, got ' + typeof states);
}
const validatorInner = useRef(validator);
const statesInner = useRef(states);
validatorInner.current = validator;
statesInner.current = states;
const [validity, setValidity] = useState(initialValidity as V);
const validate = useCallback(() => {
if (validatorInner.current.length >= 2) {
validatorInner.current(statesInner.current, setValidity);
} else {
setValidity(validatorInner.current(statesInner.current));
}
}, [setValidity]);
useEffect(() => {
validate();
}, Object.values(states));
return [validity, validate];
}