π
React Final Form
Installation
npm install --save react-final-form final-form
or
yarn add react-final-form final-form
Getting Started
You can think of it a little like GraphQL's feature of only fetching the data your component needs to render, and nothing else.
Here's what it looks like in your code:
import { Form, Field } from 'react-final-form'
const MyForm = () => (
<Form
onSubmit={onSubmit}
validate={validate}
render={({ handleSubmit, pristine, invalid }) => (
<form onSubmit={handleSubmit}>
<h2>Simple Default Input</h2>
<div>
<label>First Name</label>
<Field name="firstName" component="input" placeholder="First Name" />
</div>
<h2>An Arbitrary Reusable Input Component</h2>
<div>
<label>Interests</label>
<Field name="interests" component={InterestPicker} />
</div>
<h2>Render Function</h2>
<Field
name="bio"
render={({ input, meta }) => (
<div>
<label>Bio</label>
<textarea {...input} />
{meta.touched && meta.error && <span>{meta.error}</span>}
</div>
)}
/>
<h2>Render Function as Children</h2>
<Field name="phone">
{({ input, meta }) => (
<div>
<label>Phone</label>
<input type="text" {...input} placeholder="Phone" />
{meta.touched && meta.error && <span>{meta.error}</span>}
</div>
)}
</Field>
<button type="submit" disabled={pristine || invalid}>
Submit
</button>
</form>
)}
/>
)
Table of Contents
- Examples
- Simple Example
- Synchronous Record-Level Validation
- Synchronous Field-Level Validation
- Asynchronous Field-Level Validation
- Hybrid Synchronous/Asynchronous Record-Level Validation
- Submission Errors
- Third Party Components
- Material UI 1.0
-
π₯ Performance Optimization Through Subscriptionsπ₯ - Independent Error Component
- Loading and Initializing Values
- Field Arrays
- Calculated Fields
- Field Warnings
- Reusable Field Groups
- External Submit
- Wizard Form
- Parse and Format (and Normalize)
- Auto-Save with Debounce
- Auto-Save on Field Blur
- Custom Validation Engine
- Loading, Normalizing, Saving, and Reinitializing
-
ποΈ Downshift Type-Ahead - Redux Example
- Rendering
- API
- Types
FieldProps
allowNull?: boolean
children?: ((props: FieldRenderProps) => React.Node) | React.Node
component?: React.ComponentType<FieldRenderProps> | string
format?: ((value: any, name: string) => any) | null
isEqual?: (a: any, b: any) => boolean
name: string
parse?: ((value: any, name: string) => any) | null
render?: (props: FieldRenderProps) => React.Node
subscription?: FieldSubscription
validate?: (value: ?any, allValues: Object) => ?any
validateFields?: string[]
value?: any
FieldRenderProps
input.name: string
input.onBlur: (?SyntheticFocusEvent<*>) => void
input.onChange: (SyntheticInputEvent<*> | any) => void
input.onFocus: (?SyntheticFocusEvent<*>) => void
input.value: any
meta.active?: boolean
meta.data: Object
meta.dirty?: boolean
meta.error?: any
meta.initial?: any
meta.invalid?: boolean
meta.pristine?: boolean
meta.submitError?: any
meta.submitFailed?: boolean
meta.submitSucceeded?: boolean
meta.touched?: boolean
meta.valid?: boolean
meta.visited?: boolean
FormProps
children?: ((props: FormRenderProps) => React.Node) | React.Node
component?: React.ComponentType<FormRenderProps>
debug?: DebugFunction
decorators?: Decorator[]
initialValues?: Object
mutators?: { [string]: Mutator }
onSubmit: (values: Object, form: FormApi, callback: ?(errors: ?Object) => void) => ?Object | Promise<?Object> | void
render?: (props: FormRenderProps) => React.Node
subscription?: FormSubscription
validate?: (values: Object) => Object | Promise<Object>
validateOnBlur?: boolean
FormRenderProps
FormSpyProps
FormSpyRenderProps
- Contributors
- Backers
- Sponsors
Examples
Simple Example
Uses the built-in React inputs: input
, select
, and textarea
to build a form with no validation.
Synchronous Record-Level Validation
Introduces a whole-record validation function and demonstrates how to display errors next to fields using child render functions.
Synchronous Field-Level Validation
Introduces field-level validation functions and demonstrates how to display errors next to fields using child render functions.
Asynchronous Field-Level Validation
Demonstrates how field-level validation rules may be asynchronous (return a Promise
), as well as how to show a "validating" spinner during the lifetime of the Promise
.
Hybrid Synchronous/Asynchronous Record-Level Validation
Demonstrates how you can mix synchronous and asynchronous validation patterns at the record-level, by returning errors synchronously, and falling back to an asynchronous call (by returning a Promise
) if sync validation is passing.
Submission Errors
Demonstrates how to return submission errors from failed submits. Notice that the Promise
should resolve to the submission error (not reject). Rejection is reserved for communications or server exceptions.
Third Party Components
Demonstrates how easy it is to use third party input components. All the third party component really needs is value
and onChange
, but more complex components can accept things like errors.
Material UI 1.0
Demonstrates how to use Material UI 1.0 input components.
π₯
Performance Optimization Through Subscriptions
π₯
Demonstrates how, by restricting which parts of form state the form component needs to render, it reduce the number of times the whole form has to rerender. Yet, if some part of form state is needed inside of it, the FormSpy
component can be used to attain it.
Independent Error Component
Demonstrates how to make an independent Error component to subscribe to and display the error for any form field.
Loading and Initializing Values
Demonstrates how a form can be initialized, after fetching data, by passing in initialValues
as a prop.
Field Arrays
Demostrates how to use the <FieldArray/>
component, from react-final-form-arrays
, to render an array of inputs, as well as use push
, pop
, and remove
mutations.
Calculated Fields
Demonstrates how to use the final-form-calculate
decorator to achieve realtime field calculations through easily defined rules.
Field Warnings
Demonstrates how the power of subscriptions and mutators can be used to build a warning engine: logic to display a message next to each field that is not an error that prevents form submission.
Reusable Field Groups
Demonstrates how fields can be grouped into reusable components.
External Submit
Demonstrates how you can use document.getElementById()
or a closure to trigger a submit from outside of the form. For more information, see How can I trigger a submit from outside the form?
Wizard Form
Demonstrates how to use
Parse and Format (and Normalize)
Demonstrates how to use
parse
and format
props to control exactly how the data flows from the form state through the input and back to the form state. Notice that you can use parse
to "normalize" your values.
Auto-Save with Debounce
Demonstrates how to use a FormSpy
component to listen for value changes and automatically submit different values after a debounce period.
Auto-Save on Field Blur
Demonstrates how to use a FormSpy
component to listen for values and active field changes to automatically submit values when fields are blurred.
Custom Validation Engine
Demonstrates how incredibly extensible FormSpy
, the setFieldData
mutator, and render props are by implementing a custom validation engine completely apart from the built-in validation in
Loading, Normalizing, Saving, and Reinitializing
Demonstrates how to make a wrapper component to handle loading, normalization of data, saving, and reinitializing of the form, to maintain pristine
/dirty
state with saved data.
ποΈ
Downshift Type-Ahead
Demonstrates how to use a
Redux Example
The only reason to keep your
FormSpy
to keep a copy of your form data in the Redux store. Note that the canonical authoritative version of the data still lives in
Rendering
There are three ways to tell <Form/>
and <Field/>
what to render:
Method | How it is rendered |
---|---|
component prop |
return React.createElement(this.props.component, props) |
render prop |
return this.props.render(props) |
a render function as children |
return this.props.children(props) |
API
The following can be imported from react-final-form
.
Field : React.ComponentType<FieldProps>
A component that takes FieldProps
and renders an individual field.
Form : React.ComponentType<FormProps>
A component that takes FormProps
and surrounds your entire form.
FormSpy : React.ComponentType<FormSpyProps>
A component that takes FormSpyProps
and can listen to form state from inside an optimized <Form/>
.
version: string
The current used version of
Types
FieldProps
These are props that you pass to <Field/>
. You must provide one of the ways to render: component
, render
, or children
.
allowNull?: boolean
By default, if your value is null
, <Field/>
will convert it to ''
, to ensure controlled inputs. But if you pass true
to allowNull
, <Field/>
will give you a null
value. Defaults to false
.
children?: ((props: FieldRenderProps) => React.Node) | React.Node
A render function that is given FieldRenderProps
, as well as any non-API props passed into the <Field/>
component.
component?: React.ComponentType<FieldRenderProps> | string
A component that is given FieldRenderProps
as props, as well as any non-API props passed into the <Field/>
component.
format?: ((value: any, name: string) => any) | null
A function that takes the value from the form values and the name of the field and formats the value to give to the input. Common use cases include converting javascript Date
values into a localized date string. Almost always used in conjunction with parse
.
Note: If you pass null
to format
, it will override the default behavior of converting undefined
into ''
. If you do this, making sure your inputs are "controlled" is up to you.
isEqual?: (a: any, b: any) => boolean
See the
isEqual
.
name: string
The name of your field.
parse?: ((value: any, name: string) => any) | null
A function that takes the value from the input and name of the field and converts the value into the value you want stored as this field's value in the form. Common usecases include converting strings into Number
s or parsing localized dates into actual javascript Date
objects. Almost always used in conjuction with format
.
Note: If you pass null
to parse
, it will override the default behavior of converting ''
into undefined
, thus allowing you to have form values of ''
.
render?: (props: FieldRenderProps) => React.Node
A render function that is given FieldRenderProps
, as well as any non-API props passed into the <Field/>
component.
subscription?: FieldSubscription
A FieldSubscription
that selects all of the items of FieldState
that you wish to update for. If you don't pass a subscription
prop, it defaults to all of FieldState
.
validate?: (value: ?any, allValues: Object) => ?any
A function that takes the field value, and all the values of the form and returns an error if the value is invalid, or undefined
if the value is valid.
validateFields?: string[]
See the
validateFields
.
value?: any
This is only used for checkboxes radio buttons!
- Radio Buttons: The value of the radio button. The radio button will render as
checked
if and only if the value given here===
the value for the field in the form. - Checkboxes:
value
is specified: the checkbox will bechecked
if the value given invalue
is contained in the array that is the value for the field for the form. Checking the box will add the value to the array, and unchecking the checkbox will remove the value from the array.- no
value
is specified: the checkbox will bechecked
if the value is truthy. Checking the box will set the value totrue
, and unchecking the checkbox will set the value tofalse
.
FieldRenderProps
These are the props that <Field/>
provides to your render function or component. This object separates out the values and event handlers intended to be given to the input component from the meta
data about the field. The input
can be destructured directly into an <input/>
like so: <input {...props.input}/>
. Keep in mind that the values in meta
are dependent on you having subscribed to them with the subscription
prop
input.name: string
The name of the field.
input.onBlur: (?SyntheticFocusEvent<*>) => void
The onBlur
function can take a SyntheticFocusEvent
like it would if you had given it directly to an <input/>
component, but you can also just call it: props.input.onBlur()
to mark the field as blurred (inactive).
input.onChange: (SyntheticInputEvent<*> | any) => void
The onChange
function can take a SyntheticInputEvent
like it would if you had given it directly to an <input/>
component (in which case it will read the value out of event.target.value
), but you can also just call it: props.input.onChange(value)
to update the value of the field.
input.onFocus: (?SyntheticFocusEvent<*>) => void
The onFocus
function can take a SyntheticFocusEvent
like it would if you had given it directly to an <input/>
component, but you can also just call it: props.input.onFocus()
to mark the field as focused (active).
input.value: any
The current value of the field.
meta.active?: boolean
See the
active
.
meta.data: Object
See the
data
.
meta.dirty?: boolean
See the
dirty
.
meta.error?: any
See the
error
.
meta.initial?: any
See the
initial
.
meta.invalid?: boolean
See the
invalid
.
meta.pristine?: boolean
See the
pristine
.
meta.submitError?: any
See the
submitError
.
meta.submitFailed?: boolean
See the
submitFailed
.
meta.submitSucceeded?: boolean
See the
submitSucceeded
.
meta.touched?: boolean
See the
touched
.
meta.valid?: boolean
See the
valid
.
meta.visited?: boolean
See the
visited
.
FormProps
These are the props that you pass to <Form/>
. You must provide one of the ways to render: component
, render
, or children
.
children?: ((props: FormRenderProps) => React.Node) | React.Node
A render function that is given FormRenderProps
, as well as any non-API props passed into the <Form/>
component.
component?: React.ComponentType<FormRenderProps>
A component that is given FormRenderProps
as props, as well as any non-API props passed into the <Form/>
component.
debug?: DebugFunction
See the
debug
.
decorators?: Decorator[]
Decorator
s to apply to the form.
initialValues?: Object
See the
initialValues
.
mutators?: { [string]: Mutator }
See the
mutators
.
onSubmit: (values: Object, form: FormApi, callback: ?(errors: ?Object) => void) => ?Object | Promise<?Object> | void
See the
onSubmit
.
render?: (props: FormRenderProps) => React.Node
A render function that is given FormRenderProps
, as well as any non-API props passed into the <Form/>
component.
subscription?: FormSubscription
A FormSubscription
that selects all of the items of FormState
that you wish to update for. If you don't pass a subscription
prop, it defaults to all of FormState
.
validate?: (values: Object) => Object | Promise<Object>
See the
validate
.
validateOnBlur?: boolean
See the
validateOnBlur
.
FormRenderProps
These are the props that <Form/>
provides to your render function or component. Keep in mind that the values you receive here are dependent upon which values of FormState
you have subscribed to with the subscription
prop. This object contains everything in
FormState
as well as:
batch: (fn: () => void) => void)
A function that allows batch updates to be done to the form state. See the
batch
.
blur: (name: string) => void
A function to blur (mark inactive) any field.
change: (name: string, value: any) => void
A function to change the value of any field.
focus: (name: string) => void
A function to focus (mark active) any field.
handleSubmit: (?SyntheticEvent<HTMLFormElement>) => void
A function intended for you to give directly to the <form>
tag: <form onSubmit={handleSubmit}/>
.
initialize: (values: Object) => void
A function that initializes the form values. See the
initialize
.
mutators?: { [string]: Function }
See the
mutators
.
reset: () => void
A function that resets the form values to their last initialized values. See the
reset
.
FormSpyProps
These are the props that you pass to <FormSpy/>
. You must provide one of the ways to render: component
, render
, or children
.
children?: ((props: FormSpyRenderProps) => React.Node) | React.Node
A render function that is given FormSpyRenderProps
, as well as any non-API props passed into the <FormSpy/>
component. Will not be called if an onChange
prop is provided.
component?: React.ComponentType<FormSpyRenderProps>
A component that is given FormSpyRenderProps
as props, as well as any non-API props passed into the <FormSpy/>
component. Will not be called if an onChange
prop is provided.
onChange?: (formState: FormState) => void
A change listener that will be called with form state whenever the form state, as subscribed to by the subscription
prop, has changed. When an onChange
prop is provided, the <FormSpy/>
will not render anything.
render?: (props: FormSpyRenderProps) => React.Node
A render function that is given FormSpyRenderProps
, as well as any non-API props passed into the <FormSpy/>
component. Will not be called if an onChange
prop is provided.
subscription?: FormSubscription
A FormSubscription
that selects all of the items of FormState
that you wish to update for. If you don't pass a subscription
prop, it defaults to all of FormState
.
FormSpyRenderProps
These are the props that <FormSpy/>
provides to your render function or component. These props are of type FormState
. Keep in mind that the values you receive here are dependent upon which values of FormState
you have subscribed to with the subscription
prop. Also included will be many of the same props provided to FormRenderProps
:
batch: (fn: () => void) => void)
A function that allows batch updates to be done to the form state. See the
batch
.
blur: (name: string) => void
A function to blur (mark inactive) any field.
change: (name: string, value: any) => void
A function to change the value of any field.
focus: (name: string) => void
A function to focus (mark active) any field.
initialize: (values: Object) => void
A function that initializes the form values. See the
initialize
.
mutators?: { [string]: Function }
See the
mutators
.
reset: () => void
A function that resets the form values to their last initialized values. See the
reset
.
Contributors
This project exists thanks to all the people who contribute. [Contribute].
Backers
Thank you to all our backers!
Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]