useForm
provides an interface around an object for use in forms.
npm install --save @caesium/hook-use-form
The best
useForm
experiance comes when using Typescript.
Lets say you want to collect a users name and email for a newsletter form.
const NewsletterSignUp: React.FunctionComponent = () => {
const {formBind, bind, onSubmit} = useForm({
name: '',
email: ''
})
onSubmit((data) => {
// `data` is the forms state when it was submitted
doSignup(data.name, data.email)
})
return <form {...formBind()}>
<input {...bind('name')} />
<input {...bind('email')} />
<input type="submit" value="Sign Up!" />
</Form>
}
useForm
s output is an object with this structure:
property | type | value |
---|---|---|
bind | (field: keyof T) => {value, onChange, name} |
Used to bind to a single field. |
clear | () => void |
Function that sets the form back to its initial value. |
controlledInput | (fieldName: keyof T) => ControlledInput |
Function that is used to create input fields (See Creating your own input). |
data | T |
The current state of the form. |
formBind | () => {onSumbit} |
Used to bind a forms submit action to useForm |
onSubmit | (handler: (data: T) => void) => void |
A function which takes a callback to be used when the form is submitted. |
validate | (field: keyof T, validator: (value: any) => boolean) => void |
A function that takes the field name and validation function as arguments. |
valid | (field?: keyof T) => boolean |
A function that checks the validity of one field or the whole form and returns a boolean value. |
set | (data: T) => void |
Function to set the data to a given value. Useful if you want to use one form to edit multiple entries. |
label | `(field: keyof T) => {for} | Returns the fields label for . |
changed | (field?: keyof T) => boolean |
Has the given field, or any field changed from the intial data. |
submit | () => void |
Submit the form. |
meta | Meta |
The meta data set in options. |
You can optionally store meta data in the form state by passing a meta object in options.
const MyForm = () => {
const {formBind, meta, bind, onSubmit, set} = useForm({
name: ''
}, {meta: {userId: 0}})
onSubmit(({name}, {userId}) => {
if(userId === 0){
newUser(name)
}else{
updateUser(userId, name)
}
})
return <div>
<form {...formBind()}>
<b>{meta.userId === 0 ? 'Creating user' : 'Editing user'}</b>
<input {...bind('name')}>
</form>
<button onClick={() => {
set({name: 'First User'}, {userId: 1})
}}>Edit User 1</button>
<button onClick={() => {
set({name: 'Second User'}, {userId: 2})
}}>Edit User 2</button>
</div>
}
meta
can then be updated through the second parameter of set
. This allows you to store additional state with your form instead of using useState
in your own components.
meta
is passed to your submit handler as the second argument.
Validating fields with useForm
is easy. Going back to the earlier example, lets ensure that the email contains an @
const NewsletterSignUp: React.FunctionComponent = () => {
const {valid, bind, formBind, validate} = useForm({
name: '',
email: ''
})
validate('email', (value) => {
return value.indexOf('@') > -1
})
return <form {...formBind()}>
<input {...bind('name')} style={{color: valid('name') ? '#000' : '#f00'}} />
<input {...bind('email')} style={{color: valid('email') ? '#000' : '#f00'}} />
<input type="submit" value="Subscribe" disabled={!valid()} />
</form>
}
Sometimes simply using bind
wont work as your not using and input
and you want to have a custom input.
useForm
returns a function of controlledInput
which gives more control over a single field.
controlledInput
returns the following:
property | type | value |
---|---|---|
field | keyof T |
The current field |
value | T[field] |
The current value (connected to state) |
update | (newValue: T[field]) => void |
Change the value to the supplied value |
valid | () => boolean |
Returns a boolean value for the fields current validity |
bind | {value, onChange, name} |
The same as if you had called bind(field) directly from useForm |
id | string |
The id of the input. |
Generated using TypeDoc