-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
/
Copy pathuseMultiStateValidator.ts
41 lines (33 loc) · 1.28 KB
/
useMultiStateValidator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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];
}