mirror of
https://github.com/streamich/react-use.git
synced 2025-12-08 18:02:14 +00:00
40 lines
1.1 KiB
TypeScript
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];
|
|
}
|