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