API ReferenceReact provider and hooksFunction
useIncrementalValidation()
function useIncrementalValidation<P>( ctx, rules, values, touched, config?): IncrementalValidationResult<P>;Incrementally validates form values against a set of rules.
Each rule independently tracks its required dependsOn fields and fires as soon as those fields are
present — independent of all other rules. Required dependencies are always watched; optional
revalidateOn fields are watched without becoming presence gates. Async validators are debounced
and cancellable via AbortController.
Rules may be built inline — array identity is ignored, and whenever a rule runs it runs the current
render’s closure. If rule logic depends on inputs outside values (e.g. a threshold from props),
pass them as config.rulesKey so their change re-triggers evaluation.
The hook itself does not throw, and neither the SDK context nor a rule failure reaches the caller as
an exception: a failed rule is reported on error and suppresses that run’s partial issue list. The
one rejecting path is the returned validateAll, which rethrows the first rule failure after
committing every other rule’s result.
Type Parameters
| Type Parameter |
|---|
P |
Parameters
| Parameter | Type | Description |
|---|---|---|
ctx | SDKContext | The SDK context rules read chain and subgraph state through. An AnvilSDK instance is one, so pass useAnvilSDK’s result. |
rules | readonly ValidationRule<P>[] | Rules to evaluate. Array identity is deliberately ignored, so an inline array is fine; whenever a rule runs it runs the current render’s closure. |
values | Partial<P> | Current form values. Partial by design — a rule whose dependsOn fields are not all present is skipped, not reported. |
touched | Set<keyof P> | Fields the user has interacted with. A touched field with no verdict yet keeps isValid false, so an untouched form is not reported as invalid. |
config? | IncrementalValidationConfig | Debounce for async rules (300ms by default) and an optional rulesKey whose change re-runs every rule — the way to react to inputs that live outside values. |
Returns
IncrementalValidationResult<P>
Per-field errors and pending state (fields), the aggregate isValid, every current issue
flattened (allErrors), the first rule error if any rule failed to complete, and validateAll
for submit-time evaluation.
Example
export function StaticLOCBeneficiaryForm() { const sdk = useAnvilSDK(); const [values, setValues] = useState<Partial<CreateStaticLOCParams>>({}); const [touched, setTouched] = useState( new Set<keyof CreateStaticLOCParams>() );
// The SDK instance is the SDKContext. Each rule fires as soon as its own // dependsOn fields are present, so an untouched field reports nothing. const { fields, isValid } = useIncrementalValidation( sdk, createStaticLOCRules, values, touched ); const beneficiary = fields.beneficiary;
return ( <> <input onChange={event => // Validation owns the shape check; the raw input is cast here. setValues({ ...values, beneficiary: event.target.value as Address, }) } onBlur={() => setTouched(new Set([...touched, 'beneficiary']))} /> {beneficiary?.pending && <span>Checking…</span>} {beneficiary?.errors.map(issue => ( <p key={issue.code}>{issue.message}</p> ))} <button disabled={!isValid}>Continue</button> </> );}See
- ValidationRule for rule authoring
- runValidation for eager (submit-time) validation