MobX powered forms in React
npm install @smashing/form!npm (scoped) !npm bundle size (scoped)
- ⚡ Fast input rerenders - doesn't rerender whole form
- 🥓 Well cooked api
- 👌 Form validation based on yup
- ⚖ It's lightweight
- Basic form with validation
- Array of fields
``bash`
npm install --save @smashing/form mobx mobx-react-lite
`tsx
import * as React from 'react'
import {useForm} from '@smashing/form'
const CustomTextInput = props =>
export const MyForm = () => {
// Use useForm hook. initialValues is the only required value.
const {Form, Field, form} = useForm({
initialValues: {
email: '',
password: '',
},
onSubmit: values => console.log(values),
})
// Wrap your inputs with Form returned by useFormField
return (
returned by useForm /}`
{/ "input" is default component used by field /}
)
}
`tsx`
const {} = useForm({
initialValues,
validationSchema,
onSubmit,
validateOnBlur,
validateOnChange,
validateOnSubmit,
})
#### initialValues - required
Object containing initial values of form. Can contain nested state.
#### validationSchema - default: undefined
Read yup docs to learn more.
#### onSubmit - default: undefined
Form submit handler
#### validateOnBlur - default: false
Control if data should be validated on input blur
#### validateOnChange - default: false
Control if data should be validated on input change
#### validateOnSubmit - default: true
Control if data should be validated on form submit
You can use yup to validate form data.
`tsx
import * as React from 'react'
import * as yup from 'yup'
import {useForm} from '@smashing/form'
const TextInput = props =>
const validationSchema = yup.object().shape({
email: yup
.string()
.email('Email is not valid.')
.max(64, 'Email is too long.')
.required('This field is required.'),
password: yup
.string()
.min(6, 'Password is too short.')
.max(64, 'Password is too long.')
.required('This field is required.'),
})
export const MyForm = () => {
const {Form, Field, form} = useForm({
initialValues: {
email: '',
password: '',
},
validationSchema,
onSubmit: values => console.log(values),
})
return (
$3
You can access whole state and form actions using
form property returned from useForm.`tsx
const {form} = useForm({})
`It contains the following state:
`json
{
"isSubmitting": false,
"isValidating": false,
"isDirty": false,
"isValid": true,
"submitCount": 0,
"validateOnChange": false,
"validateOnBlur": false,
"validateOnSubmit": true,
"values": {},
"initialValues": {},
"errors": {},
"touched": {}
}
`$3
You can access form state using context.
FormContext and useFormContext are exported from package.`tsx
import {useFormContext, FormContext} from '@smashing/form'const NestedComponent = () => {
const {form} = useFormContext()
// OR const {form} = React.useContext(FormContext)
}
`>
FormContext/useFormContext can be used only inside Form component returned from useForm.$3
`tsx
const MyForm = () => {
const {Form, Field} = useForm({
initialValues: {
email: '',
social: {
twitter: '',
facebook: '',
},
friends: [{name: 'John'}, {name: 'Jane'}],
},
}) return (
)
}
`Manipulating array items:
`tsx
const {form} = useForm({
initialValues: {
friends: ['John', 'Jane'],
},
})// Add new item
form.values.friends.push('')
// Remove first item
form.values.friends.splice(0, 1)
`$3
You can operate on form state using
form object returned by useForm:`tsx
const {form} = useForm({
initialValue: {
email: '',
password: '',
},
})form.setFieldValue('email', 'john.doe@example.com')
`####
reset: (nextState?: {values: {}, errors: {}, touched: {}}): voidRest form values, errors and touch states to initial state:
`tsx
form.reset()
`Optionally
nextState object can be passed:`tsx
form.reset({
values: {email: 'john.doe@example.com'},
errors: {password: 'Password is required'},
touched: {
email: true,
password: true,
},
})
`####
submit: (): voidTrigger
onSubmit handler.####
validate: (field?: string): voidValidate all inputs:
`tsx
form.validate()
`Validate single input:
`tsx
form.validate('email')
`####
setIsSubmitting: (value: boolean): voidStart or finish submission process:
`tsx
form.setIsSubmitting(true)
`####
setValues: (values: Values): voidSet all input values:
`tsx
form.setValues({
email: '',
password: '',
})
`####
setErrors: (errors: FormErrors): voidSet all validation errors:
`tsx
form.setErrors({
email: 'Email is invalid',
password: 'Password is to short',
})
`####
setTouched: (values: FormTouched): voidSet all inputs touch state:
`tsx
form.setTouched({
email: true,
password: false,
})
`####
setFieldValue: (field: string, value: any): voidSet single field value:
`tsx
form.setFieldValue('email', 'john.doe@example.com')
`####
setFieldError: (field: string, message?: string): voidSet single field error message:
`tsx
form.setFieldError('email', 'Email is invalid')
`####
setFieldTouched: (field: string, isTouched: boolean): voidSet single field touch state:
`tsx
form.setFieldTouched('email', true)
``MIT © EYEDEA AS