β Zero dependencies
β Only peer dependencies: React and π Final Form
β Opt-in subscriptions - only update on the state you need!
β π₯ 2.5k gzipped π₯
npm install --save react-final-form final-form
or
yarn add react-final-form final-form
π React Final Form is a thin React wrapper for π Final Form, which is a subscriptions-based form state management library that uses the Observer pattern, so only the components that need updating are re-rendered as the form's state changes. By default, π React Final Form subscribes to all changes, but if you want to fine tune your form to optimized blazing-fast perfection, you may specify only the form state that you care about for rendering your gorgeous UI.
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>
)}
/>
)
- 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
- π₯ Performance Optimization Through Subscriptions π₯
- Independent Error Component
- Loading and Initializing Values
- Field Arrays
- Calculated Fields
- Rendering
- API
- Types
FieldProps
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, 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
Uses the built-in React inputs: input
, select
, and textarea
to build a
form with no validation.
Introduces a whole-record validation function and demonstrates how to display errors next to fields using child render functions.
Introduces field-level validation functions and demonstrates how to display errors next to fields using child render functions.
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
.
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.
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.
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.
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.
Demonstrates how to make an independent Error component to subscribe to and display the error for any form field.
Demonstrates how a form can be initialized, after fetching data, by passing in
initialValues
as a prop.
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.
Demonstrates how to use the
final-form-calculate
decorator to achieve realtime field calculations through easily defined rules.
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) |
The following can be imported from react-final-form
.
A component that takes FieldProps
and renders an individual
field.
A component that takes FormProps
and surrounds your entire form.
A component that takes FormSpyProps
and can listen to form
state from inside an optimized <Form/>
.
The current used version of π React Final Form.
These are props that you pass to
<Field/>
. You must provide one of the
ways to render: component
, render
, or children
.
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
.
A render function that is given FieldRenderProps
, as well
as any non-API props passed into the <Field/>
component.
A component that is given FieldRenderProps
as props, as
well as any non-API props passed into the <Field/>
component.
The name of your field.
A render function that is given FieldRenderProps
, as well
as any non-API props passed into the <Field/>
component.
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
.
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.
This is only used for 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.
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
The name of the field.
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).
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.
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).
The current value of the field.
See the π Final Form docs on active
.
See the π Final Form docs on data
.
See the π Final Form docs on dirty
.
See the π Final Form docs on error
.
See the π Final Form docs on initial
.
See the π Final Form docs on invalid
.
See the π Final Form docs on pristine
.
See the π Final Form docs on submitError
.
See the π Final Form docs on submitFailed
.
See the π Final Form docs on submitSucceeded
.
See the π Final Form docs on touched
.
See the π Final Form docs on valid
.
See the π Final Form docs on visited
.
These are the props that you pass to
<Form/>
. You must provide one of the
ways to render: component
, render
, or children
.
A render function that is given FormRenderProps
, as well
as any non-API props passed into the <Form/>
component.
A component that is given FormRenderProps
as props, as
well as any non-API props passed into the <Form/>
component.
See the π Final Form docs on debug
.
Decorator
s
to apply to the form.
See the π Final Form docs on initialValues
.
See the π Final Form docs on mutators
.
onSubmit: (values: Object, callback: ?(errors: ?Object) => void) => ?Object | Promise<?Object> | void
See the π Final Form docs on onSubmit
.
A render function that is given FormRenderProps
, as well
as any non-API props passed into the <Form/>
component.
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
.
See the π Final Form docs on validate
.
See the π Final Form docs on validateOnBlur
.
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
π Final Form's FormState
as well as:
A function that allows batch updates to be done to the form state.
See the π Final Form docs on batch
.
A function to blur (mark inactive) any field.
A function to change the value of any field.
A function to focus (mark active) any field.
A function intended for you to give directly to the <form>
tag: <form onSubmit={handleSubmit}/>
.
A function that initializes the form values.
See the π Final Form docs on initialize
.
See the π Final Form docs on mutators
.
A function that resets the form values to their last initialized values.
See the π Final Form docs on reset
.
These are the props that you pass to
<FormSpy/>
. You must provide one
of the ways to render: component
, render
, or children
.
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.
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.
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.
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.
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
.
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.