Skip to content

useStateValidator

Custom useState hook that validates state on every update.

Demo

INFO

The component uses useStateValidator hook to declare a state object with name and email properties attached to two input tag and validates them during typing.

Loading demo…
Show source code
tsx
import { useStateValidator } from "../../../.."

export const UseStateValidator = () => {
	const [state, setState, validation] = useStateValidator(
		{
			name: "", email: ""
		},
		(state, validation) => {
			if (state.name.length > 10) {
				validation.name.invalid = true;
				validation.name.message = "Max Length 10 characters"
			}
			if (!state.email.includes("@")) {
				validation.email.invalid = true;
				validation.email.message = "@ is missing"
			}
			return validation;
		}
	);

	return <div>
		<div style={{display: "flex", flexDirection: "column", width: 'fit-content', margin: "0 auto"}}>
			<input type="text" name="name" value={state.name} onChange={e => setState(s => ({...s, [e.target.name]: e.target.value}))} />
			{
				validation.name.invalid &&
				<span style={{ color: "red" }}>{validation.name.message}</span>
			}
		</div>
		<div style={{display: "flex", flexDirection: "column", width: 'fit-content', margin: "0 auto"}}>
			<input type="text" name="email" value={state.email} onChange={e => setState(s => ({...s, [e.target.name]: e.target.value}))} />
			{
				validation.email.invalid &&
				<span style={{ color: "red" }}>{validation.email.message}</span>
			}
		</div>
	</div>
}

Types

StateValidator

  • @template T Type of the validated state. * ### Overloads - Object state — both this context and the first argument receive the full object; the validation argument is shaped as { [key in keyof T]: ValidationEntry }. - Primitive state — the first argument is the primitive value; the validation argument is a single ValidationEntry.

Validator function accepted by useStateValidator.

The function is called on every state update and must return the (possibly mutated) validation argument so React can detect changes.

InputInput DescriptionReturnReturn Description
(this: T, state: T, validation: T extends object ? {[k in keyof T]: {invalid: boolean, message?: string}}: {invalid: boolean, message?: string})Validator function accepted by useStateValidator. The function is called on every state update and must return the (possibly mutated) validation argument so React can detect changes.typeof validation;
(state: T, validation: T extends object ? { [k in keyof T]: {invalid: boolean, message?: string} } : {invalid: boolean, message?: string})Validator function accepted by useStateValidator. The function is called on every state update and must return the (possibly mutated) validation argument so React can detect changes.typeof validation;

UseStateValidatorProps

  • @template T - The type of the state value being validated.

Parameters accepted by useStateValidator.

PropertyTypeRequiredDescription
initialStateT \| (() => T)The initial state value. Accepts either a direct value or a lazy initializer function invoked only on the first render.
validatorStateValidator<T>A validator function or configuration object that defines the validation rules applied to the state. See {@link StateValidator}.

UseStateValidatorResult

  • @template T - The type of the state value being validated.

Return value of useStateValidator.

IndexTypeDescription
[0]TThe current state value, reactive — triggers a re-render when updated.
[1]Dispatch<SetStateAction<T>>A stable setter (same semantics as the setter returned by useState). Accepts either a new value or an updater function receiving the current state and returning the next. Triggers re-validation after each update.
[2]T extends object ? { [k in keyof T]: { invalid: boolean; message?: string } } : { invalid: boolean; message?: string }The current validation result, updated synchronously after each state change. Shape depends on T: - When T is an object — a mirrored object where each key maps to { invalid: boolean, message?: string }, allowing per-field validation feedback. - When T is a primitive — a single { invalid: boolean, message?: string } object describing the overall validity of the value.

Released under the MIT License.