High performance subscription-based form state management for React
npx @tessl/cli install tessl/npm-react-final-form@7.0.00
# React Final Form
1
2
React Final Form is a high-performance, subscription-based form state management library for React applications. Built as a thin wrapper around Final Form, it provides efficient form handling through the Observer pattern with zero dependencies that affect bundle size and a tiny 3.0k gzipped footprint.
3
4
## Package Information
5
6
- **Package Name**: react-final-form
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install react-final-form`
10
11
## Core Imports
12
13
```typescript
14
import {
15
Form,
16
Field,
17
FormSpy,
18
useForm,
19
useField,
20
useFormState,
21
withTypes,
22
version,
23
all
24
} from "react-final-form";
25
26
// Import types from react-final-form
27
import type {
28
FormProps,
29
FieldProps,
30
FormSpyProps,
31
FieldRenderProps,
32
FormRenderProps,
33
UseFieldConfig,
34
UseFormStateParams,
35
ReactContext,
36
FormSpyPropsWithForm,
37
FieldInputProps,
38
RenderableProps,
39
SubmitEvent,
40
UseFieldAutoConfig
41
} from "react-final-form";
42
43
// Import types from final-form (peer dependency)
44
import type {
45
FormApi,
46
FormState,
47
FieldState,
48
FormSubscription,
49
FieldSubscription,
50
Config,
51
Decorator,
52
FieldValidator
53
} from "final-form";
54
```
55
56
For CommonJS:
57
58
```javascript
59
const {
60
Form,
61
Field,
62
FormSpy,
63
useForm,
64
useField,
65
useFormState,
66
withTypes,
67
version,
68
all
69
} = require("react-final-form");
70
```
71
72
## Basic Usage
73
74
```typescript
75
import React from "react";
76
import { Form, Field } from "react-final-form";
77
78
interface FormValues {
79
firstName: string;
80
lastName: string;
81
email: string;
82
}
83
84
const onSubmit = (values: FormValues) => {
85
console.log(values);
86
};
87
88
function MyForm() {
89
return (
90
<Form<FormValues>
91
onSubmit={onSubmit}
92
render={({ handleSubmit, form, submitting, pristine, values }) => (
93
<form onSubmit={handleSubmit}>
94
<Field name="firstName">
95
{({ input, meta }) => (
96
<div>
97
<label>First Name</label>
98
<input {...input} type="text" placeholder="First Name" />
99
{meta.error && meta.touched && <span>{meta.error}</span>}
100
</div>
101
)}
102
</Field>
103
104
<Field name="email">
105
{({ input, meta }) => (
106
<div>
107
<label>Email</label>
108
<input {...input} type="email" placeholder="Email" />
109
{meta.error && meta.touched && <span>{meta.error}</span>}
110
</div>
111
)}
112
</Field>
113
114
<button type="submit" disabled={submitting}>
115
Submit
116
</button>
117
<button
118
type="button"
119
onClick={form.reset}
120
disabled={submitting || pristine}
121
>
122
Reset
123
</button>
124
</form>
125
)}
126
/>
127
);
128
}
129
```
130
131
## Architecture
132
133
React Final Form is built around several key components:
134
135
- **Form Component**: Root form wrapper that provides form context and manages form state
136
- **Field Component**: Individual field components that subscribe to specific field state
137
- **Hooks API**: Modern React hooks for accessing form and field state
138
- **Subscription System**: Opt-in subscriptions ensure only components requiring updates are re-rendered
139
- **Render Props**: Flexible rendering patterns supporting both render props and children functions
140
- **Type Safety**: Full TypeScript support with generic type preservation
141
142
## Capabilities
143
144
### Form Management
145
146
Core form wrapper component that provides form context, state management, and submission handling with efficient subscription-based updates.
147
148
```typescript { .api }
149
const Form: <FormValues = Record<string, any>>(
150
props: FormProps<FormValues>
151
) => React.ReactElement;
152
153
interface FormProps<FormValues = Record<string, any>>
154
extends Config<FormValues>,
155
RenderableProps<FormRenderProps<FormValues>> {
156
subscription?: FormSubscription;
157
decorators?: Decorator<FormValues>[];
158
form?: FormApi<FormValues>;
159
initialValuesEqual?: (
160
a?: Record<string, any>,
161
b?: Record<string, any>
162
) => boolean;
163
}
164
165
interface FormRenderProps<FormValues = Record<string, any>>
166
extends FormState<FormValues> {
167
handleSubmit: (
168
event?: SubmitEvent
169
) => Promise<Record<string, any> | undefined> | undefined;
170
form: FormApi<FormValues>;
171
}
172
```
173
174
[Form Component](./form.md)
175
176
### Field Management
177
178
Individual field components with subscription-based state management, validation, formatting, and parsing capabilities.
179
180
```typescript { .api }
181
const Field: <
182
FieldValue = any,
183
T extends HTMLElement = HTMLElement,
184
FormValues = Record<string, any>
185
>(
186
props: FieldProps<FieldValue, T, FormValues>
187
) => React.ReactElement;
188
189
interface FieldProps<
190
FieldValue = any,
191
T extends HTMLElement = HTMLElement,
192
FormValues = Record<string, any>
193
> extends UseFieldConfig,
194
Omit<RenderableProps<FieldRenderProps<FieldValue, T>>, "children"> {
195
name: string;
196
children?: RenderableProps<FieldRenderProps<FieldValue, T>>["children"];
197
[key: string]: any;
198
}
199
200
interface FieldRenderProps<
201
FieldValue = any,
202
T extends HTMLElement = HTMLElement,
203
FormValues = any
204
> {
205
input: FieldInputProps<FieldValue, T>;
206
meta: {
207
active?: boolean;
208
data?: Record<string, any>;
209
dirty?: boolean;
210
dirtySinceLastSubmit?: boolean;
211
error?: any;
212
initial?: any;
213
invalid?: boolean;
214
length?: number;
215
modified?: boolean;
216
modifiedSinceLastSubmit?: boolean;
217
pristine?: boolean;
218
submitError?: any;
219
submitFailed?: boolean;
220
submitSucceeded?: boolean;
221
submitting?: boolean;
222
touched?: boolean;
223
valid?: boolean;
224
validating?: boolean;
225
visited?: boolean;
226
};
227
}
228
```
229
230
[Field Component](./field.md)
231
232
### Form State Observation
233
234
FormSpy component for observing form state changes without rendering form fields, perfect for external components that need form state updates.
235
236
```typescript { .api }
237
const FormSpy: <FormValues = Record<string, any>>(
238
props: FormSpyProps<FormValues>
239
) => React.ReactElement;
240
241
interface FormSpyProps<FormValues = Record<string, any>>
242
extends UseFormStateParams<FormValues>,
243
RenderableProps<FormSpyRenderProps<FormValues>> {}
244
245
interface FormSpyRenderProps<FormValues = Record<string, any>>
246
extends FormState<FormValues> {
247
form: FormApi<FormValues>;
248
}
249
```
250
251
[Form Spy](./form-spy.md)
252
253
### Hooks API
254
255
Modern React hooks for accessing form context, field state, and form state with customizable subscriptions and full TypeScript support.
256
257
```typescript { .api }
258
function useForm<FormValues = Record<string, any>>(
259
componentName?: string
260
): FormApi<FormValues>;
261
262
function useField<
263
FieldValue = any,
264
T extends HTMLElement = HTMLElement,
265
FormValues = Record<string, any>
266
>(
267
name: string,
268
config?: UseFieldConfig
269
): FieldRenderProps<FieldValue, T, FormValues>;
270
271
function useFormState<FormValues = Record<string, any>>(
272
params?: UseFormStateParams<FormValues>
273
): FormState<FormValues>;
274
```
275
276
[Hooks API](./hooks.md)
277
278
### TypeScript Integration
279
280
Utility functions and type helpers for enhanced TypeScript support with strongly typed form and field components.
281
282
```typescript { .api }
283
function withTypes<FormValues = Record<string, any>>(): {
284
Form: React.ComponentType<FormProps<FormValues>>;
285
FormSpy: React.ComponentType<FormSpyProps<FormValues>>;
286
};
287
288
const version: string;
289
290
const all: FormSubscription;
291
```
292
293
[TypeScript Support](./typescript.md)
294
295
## Core Types
296
297
```typescript { .api }
298
interface FieldInputProps<
299
FieldValue = any,
300
T extends HTMLElement = HTMLElement
301
> {
302
name: string;
303
onBlur: (event?: React.FocusEvent<T>) => void;
304
onChange: (event: React.ChangeEvent<T> | any) => void;
305
onFocus: (event?: React.FocusEvent<T>) => void;
306
value: FieldValue;
307
checked?: boolean;
308
multiple?: boolean;
309
type?: string;
310
}
311
312
interface RenderableProps<T> {
313
component?: React.ComponentType<any> | SupportedInputs;
314
children?: ((props: T) => React.ReactNode) | React.ReactNode;
315
render?: (props: T) => React.ReactNode;
316
}
317
318
interface SubmitEvent {
319
preventDefault?: () => void;
320
stopPropagation?: () => void;
321
}
322
323
interface UseFormStateParams<FormValues = Record<string, any>> {
324
onChange?: (formState: FormState<FormValues>) => void;
325
subscription?: FormSubscription;
326
}
327
328
interface UseFieldConfig extends UseFieldAutoConfig {
329
subscription?: FieldSubscription;
330
}
331
332
interface UseFieldAutoConfig {
333
afterSubmit?: () => void;
334
allowNull?: boolean;
335
beforeSubmit?: () => void | false;
336
component?: RenderableProps<any>["component"];
337
data?: Record<string, any>;
338
defaultValue?: any;
339
format?: (value: any, name: string) => any;
340
formatOnBlur?: boolean;
341
initialValue?: any;
342
isEqual?: (a: any, b: any) => boolean;
343
multiple?: boolean;
344
parse?: (value: any, name: string) => any;
345
type?: string;
346
validate?: FieldValidator<any>;
347
validateFields?: string[];
348
value?: any;
349
}
350
351
interface ReactContext<FormValues = Record<string, any>> {
352
reactFinalForm: FormApi<FormValues>;
353
}
354
355
interface FormSpyPropsWithForm<FormValues = Record<string, any>>
356
extends FormSpyProps<FormValues> {
357
reactFinalForm: FormApi<FormValues>;
358
}
359
360
type SupportedInputs = "input" | "select" | "textarea";
361
```