fielder
Version:
A field-first form library for React and React Native
103 lines (79 loc) • 2.56 kB
text/mdx
_Validation is one of the key ways in which `Fielder` differentiates itself from other libraries._
Any provided validation function will be triggered immediately on either of these events:
- `mount` - on field mount/remount.
- `change` - on value change.
- `blur` - on blur event.
- `update` - on _any_ change event across the form (see [cross form validation](#cross-form-validation)).
- `submit` - on submit handler called.
## Basic validation
Validation is as simple as providing a function to `useField` which is called on each [validation event](#validation-events).
```tsx
const MyField = () => {
const [passwordProps, passwordMeta] = useField({
name: 'password'
validate: validatePassword
});
return (
<>
<input type="password" {...passwordProps} />
{passwordMeta.hasBlurred && passwordMeta.error}
</>
);
};
const validatePassword = ({ value }) => {
if (!value || value.length < 8) {
throw Error("Password must be 8 characters long");
}
};
```
The `trigger` argument can be used to cater validation to specific events; such as triggering asynchronous validation on submit.
```tsx
const validateUsername = ({ trigger, value }) => {
// Ignore other field updates
if (trigger === 'update') {
return;
}
// Ensure username exists (mount, change, blur, submit)
if (!value) {
throw Error('Username is required');
}
// Check if username is taken (submit)
if (trigger === 'submit') {
return isUsernameFree(value).then((isFree) => {
if (!isFree) {
throw Error('Username is already taken');
}
});
}
};
```
The `form` argument can be used to conditionally validate a field based on other field values in the form.
```tsx
const validatePasswordConfirmation = ({ value, form }) => {
// Wait for password validation first
if (!form.password.isValid) {
return;
}
if (value !== form.password.value) {
throw Error('Password confirmation does not match');
}
};
```
Memoised validation functions dependent on state outside of the form can be used.
> Changes to validation functions will retrigger the last mount/change/blur event
```tsx
const { addressIsRequired } = useSomeExternalState();
const [fieldProps, fieldMeta] = useField({
name: 'address'
validate: useCallback(({ value }) => {
if (addressIsRequired && !value) {
throw Error("Address is required");
}
}, [addressIsRequired])
});
```