|
1 | 1 | import { useCallback, useEffect, useRef, useState } from 'react';
|
2 |
| -import { DispatchValidity, UseValidatorReturn, ValidityState } from './useStateValidator'; |
| 2 | +import { StateValidator, UseStateValidatorReturn, ValidityState } from './useStateValidator'; |
3 | 3 |
|
4 | 4 | export type MultiStateValidatorStates = any[] | { [p: string]: any } | { [p: number]: any };
|
| 5 | +export type MultiStateValidator<V extends ValidityState, S extends MultiStateValidatorStates> = StateValidator<V, S>; |
5 | 6 |
|
6 |
| -export interface MultiStateValidator< |
7 |
| - V extends ValidityState = ValidityState, |
8 |
| - S extends MultiStateValidatorStates = MultiStateValidatorStates |
9 |
| -> { |
10 |
| - (states: S): V; |
11 |
| - |
12 |
| - (states: S, done: DispatchValidity<V>): void; |
13 |
| -} |
14 |
| - |
15 |
| -export function useMultiStateValidator< |
16 |
| - V extends ValidityState = ValidityState, |
17 |
| - S extends MultiStateValidatorStates = MultiStateValidatorStates |
18 |
| ->(states: S, validator: MultiStateValidator<V, S>, initialValidity: V = [undefined] as V): UseValidatorReturn<V> { |
| 7 | +export function useMultiStateValidator<V extends ValidityState, S extends MultiStateValidatorStates, I extends V>( |
| 8 | + states: S, |
| 9 | + validator: MultiStateValidator<V, S>, |
| 10 | + initialValidity: I = [undefined] as I |
| 11 | +): UseStateValidatorReturn<V> { |
19 | 12 | if (typeof states !== 'object') {
|
20 | 13 | throw new Error('states expected to be an object or array, got ' + typeof states);
|
21 | 14 | }
|
22 | 15 |
|
23 |
| - const validatorFn = useRef(validator); |
| 16 | + const validatorInner = useRef(validator); |
| 17 | + const statesInner = useRef(states); |
| 18 | + |
| 19 | + validatorInner.current = validator; |
| 20 | + statesInner.current = states; |
24 | 21 |
|
25 |
| - const [validity, setValidity] = useState(initialValidity); |
| 22 | + const [validity, setValidity] = useState(initialValidity as V); |
26 | 23 |
|
27 |
| - const deps = Array.isArray(states) ? states : Object.values(states); |
28 | 24 | const validate = useCallback(() => {
|
29 |
| - if (validatorFn.current.length === 2) { |
30 |
| - validatorFn.current(states, setValidity); |
| 25 | + if (validatorInner.current.length >= 2) { |
| 26 | + validatorInner.current(statesInner.current, setValidity); |
31 | 27 | } else {
|
32 |
| - setValidity(validatorFn.current(states)); |
| 28 | + setValidity(validatorInner.current(statesInner.current)); |
33 | 29 | }
|
34 |
| - }, deps); |
| 30 | + }, [setValidity]); |
35 | 31 |
|
36 | 32 | useEffect(() => {
|
37 | 33 | validate();
|
38 |
| - }, deps); |
| 34 | + }, Object.values(states)); |
39 | 35 |
|
40 | 36 | return [validity, validate];
|
41 | 37 | }
|
0 commit comments