React Validator Hook
A React Hook to handle form validation messages.
Features:
- multiple rules per field
- asynchronous rules with built-in concurrency prevention
- BYO rules and display logic
Install
npm i react-use-validator
Usage
See validator-creator for background information about validator rules.
;; const initialFormData = field1: "" field2: ""; // A rule defines how a value should be validated. This is a rule that ensures// string values aren't empty.const filled = ; { const formData setFormData = ; // useValidator() accepts a "rule collection" listing the validation rules // to apply to each field. // The `messages` element contains the messages for fields that have failed. // The `validate` element is a function used to perform a validation. const messages validate = ; { const change = name: value ; ; // the change is validated which will update `messages` if there's a change // to the validation results ; } { // the whole form is validated prior to submitting const messages = await ; if Object length > 0 // abort as there's at least one non-null message return; // continue as there are no validation messages await API; // or something } return <div> <div> <label>Field 1</label> <input name="field1" value=formDatafield1 onChange=handleChange /> // The message output will display "Required" from the `filled` rule if // the input value is empty <span>messagesfield1</span> </div> <div> <label>Field 2</label> <input name="field2" value=formDatafield2 onChange=handleChange /> <span>messagesfield2</span> </div> <button onClick=handleSubmit>Submit</button> </div> ;}
Asynchronous rules
The validator handles asynchronous validation rules (such as server-side validation), but some care is required.
An asynchronous rule can be created using the createAsyncRule
function.
;; // createAsyncRule(validate, payload) is used to create a rule function// The `validate` argument is a callback provided by your app. It should return// a promise that resolves with a list of validation results. A validation result// is an object with shape `{ type, prop }` which identifies the rule (`type`) and// field (`prop`) that triggered the error// The `payload` argument allows control over the error message.const server = ;
The rule can be added to a rule collection in the same way as for synchronous rules.
const rules = field1: filled server field2: filled server;
- Rules are executed in the order they appear in the rule collection, stopping at the first one that returns a non-null response.
- Asynchronous rules will only be called once per validation.
The validate()
function returned by useValidator
will prevent concurrent
calls to the same rule by throwing a ValidatorError exception if a call is
interrupted. This exception should be caught (and usually ignored) by the
Component
{ if !error instanceof ValidatorError throw error; } { const change = name: value ; ; await ;}
If a "submit" event occurs while an asynchronous validation is still in progress
the event handler can block until the validation completes by calling
validate()
with no arguments. Again, ValidatorError
exceptions should be
caught and used to prevent further execution of the handler.
{ try const messages = await ; // ... check if there are any messages ... catch error return ; // ... continue submitting data ...}
Even after all validation rules have passed, submitting form data to the server
may still fail. If the server response contains a list of errors with
validation results ({ type, prop }
objects) the validator can be re-run
providing those errors so that another network request isn't needed.
{ // ... check there are no messages ... const response = await API; if responseerrors // inject server errors into the validator await ; else // ... handle successful submit ... }