A type-safe approach to managing complex form state in React.
npm install @stackup/formA type-safe approach to managing complex form state in React.
This library provides integration with @stackup/validate to handle validation. However, it should be pretty easy to integrate whatever validation library you prefer.
You should also checkout @stackup/inputs, which includes some ready-made form fields.
``jsx
import React from "react";
import { useForm, useField } from "@stackup/form";
const Form = () => {
const form = useForm({ initialValue: { email: "", name: "" } });
const validate = useValidation(form, value => {
if (value.email) {
return { valid: true, value };
} else {
return { valid: false, error: { email: "is required" } };
}
});
const submit = useSubmit(validate, value => {
console.log(value);
});
return (
const Input = ({
label,
field: { id, value, error, touched, setValue, setTouched },
...props
}) => (
{error}
}API
#### Table of Contents
- useForm
- useField
- useValidation
- useValidate
- useSubmit
- useReset
- useFieldItem
- usePushItem
- useInsertItem
- useRemoveItem
- useIdentifier
- Form
- FormField
- ValidateFn
- Submit
- Submission
- Reset
- UseFormOptions
- UseValidationOptions
$3
Create a new form. A form requires an initial value, a function to validate,
and a submit handler.
A form behaves just like any other field, but with some extra properties for
managing submission.
The initial value for the form can be literally anything! Usually, it's an
object, but it could be any type of value.
#### Parameters
-
options UseFormOptions<Value>#### Examples
Form values can be primitive
`javascript
const form = useForm({ initialValue: "" });
`But usually, they'll contain an object
`javascript
const form = useForm({
initialValue: {
email: "",
name: ""
}
});
`Returns Form<Value>
$3
Create a field for a given property.
#### Parameters
-
field FormField<Value>
- name Name#### Examples
`javascript
const form = useForm({
initialValue: {
email: "",
profile: { name: "" } }
}
});const email = useField(form, "email");
const profile = useField(form, "profile");
const name = useField(profile, "name");
`Returns FormField<any>
$3
Use a plain ol' function for validation.
This hook can also be used to incorporate your favorite validation library.
#### Parameters
-
form Form<Value, Value>
- fn ValidateFn<Value, Result>
- opts UseValidationOptions (optional, default {})#### Examples
`javascript
const validation = useValidation(form, value => {
if (!value.email) {
return { valid: false, error: { email: "can't be blank" } };
} return { valid: true, value };
});
`Returns Form<Value, Result>
$3
Add validation to the form using @stackup/validate.
#### Parameters
-
form Form<Value, Value>
- validator Validator<(Value | any), Result>
- opts UseValidationOptions?#### Examples
`javascript
const validator = schema({
email: assert(isString).then(refute(isBlank))
});const validate = useValidate(form, validator);
`Returns Form<Value, Result>
$3
Create a submit handler for the form.
#### Parameters
-
form Form<Value, Result>
- fn SubmitFn<Result>
- opts ValidateOptions (optional, default {touch:true})#### Examples
Sumbitting a form
`javascript
const form = useForm({ initialValue: "foo" });
const submit = useSubmit(form, console.log);
`Sumbitting with validation
`javascript
const form = useForm({ initialValue: "foo" });
const validate = useValidate(form, myValidator);
const submit = useSubmit(validate, console.log);
`Returns Submit
$3
Create a reset handler for the form.
#### Parameters
-
form Form<Value, Result>#### Examples
`javascript
const form = useForm({ initialValue: "foo" });
const reset = useReset(form);
`Returns Reset
$3
Create a field for a specific index in an array.
This hook is intended for use in building forms with "Add another" functionality.
#### Parameters
-
field FormField<Array<Value>>
- index number#### Examples
`javascript
const form = useForm({ initialValue: { pets: [{ name: "" }] } });
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const name = useField(pet, "name");
`Returns FormField<Value>
$3
Adds a new value to the end to an array of values.
This can be used to create a form with repeating fields.
#### Parameters
-
field FormField<Array<Value>>
- value Value#### Examples
`javascript
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const addPet = usePushItem(pets, { name: "" });
`$3
Adds a new value at a specific position to an array of values.
This can be used to create a form with repeating fields.
#### Parameters
-
field FormField<Array<Value>>
- index number
- value Value#### Examples
`javascript
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const insert = useInsertItem(pets, 0, { name: "" });
`$3
Removes a value at the given index from array of values.
This can be used to create a form with repeating fields.
#### Parameters
-
field FormField<Array<Value>>
- index number#### Examples
`javascript
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const removePet = useRemoveItem(pets, 0);
`$3
Creates a unique identifier that will remain consistent across re-renders.
This hook does not currently support SSR.
#### Parameters
-
id string?Returns string
$3
Extends FormField<Value>
The value returned by
useForm.#### initialValue
The initial values for the form.
Type: Value
#### initialError
The initial errors on the fields.
Type: FormError<Value>
#### initialTouched
The initially touched fields.
Type: FormTouched<Value>
#### setValidating
Indicate that the form is validating
Type: SetState<boolean>
#### setSubmitting
Indicate that the form is validating
Type: SetState<boolean>
#### setSubmission
Update the form's submission status
Type: SetState<Submission>
#### reset
Reset the state of the form
Type: function (opts: ResetOptions<Value>): void
#### validate
Run validation
Type: function (opts: ValidateOptions): Promise<ValidationResult<Value, Result>>
$3
The primary form data structure.
#### id
A unique ID for this form field. This can be used to associate fields with a label.
Type: string
#### name
The name or array index that was given to useField or useFieldItem.
#### value
The current value of the field.
Type: Value
#### error
An error or errors that are associated with this field or it's children.
Type: FormError<Value>
#### touched
Indicates that this field or it's children have been modified by the user.
Type: FormTouched<Value>
#### isValidating
Indicates that validation is currently being run
Type: boolean
#### isSubmitting
Indicates that the form is currently being submitted
Type: boolean
#### submission
Keeps track of the form's submission status
Type: Submission
#### setValue
Change the value. Just like with
setState, you can pass a callback
to this function to get the current value and update it.Type: SetState<Value>
#### setError
Update the error.
Type: SetState<FormError<Value>>
#### setTouched
Indicate that this field has been touched. This is usually called in
onBlur.Type: SetState<FormTouched<Value>>
$3
A function used for validation. This function must indicate whether
or not the form is valid.
The
error property can be used to set errors on the form.The
value` property can be used to transform the form's values beforeType: function (value: Value): (ValidationResult<Value, Result> | PromiseLike<ValidationResult<Value, Result>>)
Submits the form.
Type: function (event: FormEvent<HTMLFormElement>): Promise<void>
Keeps track of submissions.
#### count
The number of times the form has been submitted
Type: number
#### error
If the submission flow throws an error, it will appear here.
Type: Error
Resets the form.
Type: function (event: FormEvent<HTMLFormElement>): Promise<void>
The options that can be passed to useForm.
#### id
Customize the base ID for all fields.
Type: string
#### initialValue
The initial values for the form.
Type: Value
#### initialError
The initial errors on the fields.
Type: FormError<Value>
#### initialTouched
The initially touched fields.
Type: FormTouched<Value>
Configures when validation runs.
#### onChange
Enables validation whenever values change.
Type: boolean
#### onBlur
Enables validation whenever a field is touched.
Type: boolean