or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

field.mdform-spy.mdform.mdhooks.mdindex.mdtypescript.md

form.mddocs/

0

# Form Component

1

2

Core form wrapper component that provides form context, state management, and submission handling with efficient subscription-based updates.

3

4

## Capabilities

5

6

### Form Component

7

8

The main Form component that wraps form elements and provides form state management through React context.

9

10

```typescript { .api }

11

/**

12

* Main form wrapper component providing form context and state management

13

* @param props - Form configuration and render props

14

* @returns React element with form context

15

*/

16

const Form: <FormValues = Record<string, any>>(

17

props: FormProps<FormValues>

18

) => React.ReactElement;

19

20

interface FormProps<FormValues = Record<string, any>>

21

extends Config<FormValues>,

22

RenderableProps<FormRenderProps<FormValues>> {

23

/** Form state subscription configuration */

24

subscription?: FormSubscription;

25

/** Form decorators for additional functionality */

26

decorators?: Decorator<FormValues>[];

27

/** External form API instance */

28

form?: FormApi<FormValues>;

29

/** Custom equality function for initial values comparison */

30

initialValuesEqual?: (

31

a?: Record<string, any>,

32

b?: Record<string, any>

33

) => boolean;

34

}

35

36

interface FormRenderProps<FormValues = Record<string, any>>

37

extends FormState<FormValues> {

38

/** Form submission handler with event handling */

39

handleSubmit: (

40

event?: SubmitEvent

41

) => Promise<Record<string, any> | undefined> | undefined;

42

/** Form API instance for programmatic control */

43

form: FormApi<FormValues>;

44

}

45

```

46

47

**Usage Examples:**

48

49

```typescript

50

import React from "react";

51

import { Form } from "react-final-form";

52

53

// Basic form with render prop

54

function BasicForm() {

55

return (

56

<Form

57

onSubmit={(values) => console.log(values)}

58

render={({ handleSubmit, pristine, invalid }) => (

59

<form onSubmit={handleSubmit}>

60

{/* form fields */}

61

<button type="submit" disabled={pristine || invalid}>

62

Submit

63

</button>

64

</form>

65

)}

66

/>

67

);

68

}

69

70

// Form with initial values and validation

71

function ValidatedForm() {

72

const validate = (values: any) => {

73

const errors: any = {};

74

if (!values.firstName) {

75

errors.firstName = "Required";

76

}

77

return errors;

78

};

79

80

return (

81

<Form

82

onSubmit={(values) => console.log(values)}

83

initialValues={{ firstName: "John" }}

84

validate={validate}

85

render={({ handleSubmit, form, submitting, values }) => (

86

<form onSubmit={handleSubmit}>

87

{/* form fields */}

88

<button type="submit" disabled={submitting}>

89

Submit

90

</button>

91

<button type="button" onClick={form.reset}>

92

Reset

93

</button>

94

<pre>{JSON.stringify(values, null, 2)}</pre>

95

</form>

96

)}

97

/>

98

);

99

}

100

101

// Form with children function

102

function ChildrenForm() {

103

return (

104

<Form onSubmit={(values) => console.log(values)}>

105

{({ handleSubmit, submitting }) => (

106

<form onSubmit={handleSubmit}>

107

{/* form fields */}

108

<button type="submit" disabled={submitting}>

109

Submit

110

</button>

111

</form>

112

)}

113

</Form>

114

);

115

}

116

```

117

118

### Form Subscription Configuration

119

120

The Form component supports customizable subscriptions to optimize rendering performance by only updating when specific form state changes occur.

121

122

```typescript { .api }

123

interface FormSubscription {

124

active?: boolean;

125

dirty?: boolean;

126

dirtyFields?: boolean;

127

dirtySinceLastSubmit?: boolean;

128

error?: boolean;

129

errors?: boolean;

130

hasSubmitErrors?: boolean;

131

hasValidationErrors?: boolean;

132

initialValues?: boolean;

133

invalid?: boolean;

134

modified?: boolean;

135

modifiedSinceLastSubmit?: boolean;

136

pristine?: boolean;

137

submitError?: boolean;

138

submitErrors?: boolean;

139

submitFailed?: boolean;

140

submitSucceeded?: boolean;

141

submitting?: boolean;

142

touched?: boolean;

143

valid?: boolean;

144

validating?: boolean;

145

values?: boolean;

146

visited?: boolean;

147

}

148

```

149

150

**Usage Example:**

151

152

```typescript

153

import { Form } from "react-final-form";

154

155

function OptimizedForm() {

156

return (

157

<Form

158

onSubmit={(values) => console.log(values)}

159

subscription={{ submitting: true, pristine: true, invalid: true }}

160

render={({ handleSubmit, submitting, pristine, invalid }) => (

161

<form onSubmit={handleSubmit}>

162

{/* Only re-renders when submitting, pristine, or invalid changes */}

163

<button type="submit" disabled={submitting || pristine || invalid}>

164

Submit

165

</button>

166

</form>

167

)}

168

/>

169

);

170

}

171

```

172

173

### Form Configuration Options

174

175

The Form component accepts all configuration options from the underlying Final Form library through the Config interface.

176

177

```typescript { .api }

178

interface Config<FormValues = Record<string, any>> {

179

/** Debug mode for development */

180

debug?: (state: FormState<FormValues>, action: string) => void;

181

/** Whether to destroy field state when field is unregistered */

182

destroyOnUnregister?: boolean;

183

/** Initial form values */

184

initialValues?: Partial<FormValues>;

185

/** Whether to keep dirty values when reinitializing */

186

keepDirtyOnReinitialize?: boolean;

187

/** Custom mutators for form state manipulation */

188

mutators?: Record<string, Mutator<FormValues>>;

189

/** Form submission handler */

190

onSubmit: (

191

values: FormValues,

192

form: FormApi<FormValues>,

193

callback?: (errors?: SubmissionErrors) => void

194

) => SubmissionErrors | Promise<SubmissionErrors> | undefined | void;

195

/** Form-level validation function */

196

validate?: (values: FormValues) => ValidationErrors | Promise<ValidationErrors>;

197

/** Values to validate on each change */

198

validateOnBlur?: boolean;

199

}

200

```

201

202

### Error Handling

203

204

Forms provide comprehensive error handling through multiple error sources and clear error state management.

205

206

```typescript { .api }

207

interface FormState<FormValues = Record<string, any>> {

208

/** Current form validation errors */

209

errors?: ValidationErrors;

210

/** Submission errors from the last submit attempt */

211

submitErrors?: SubmissionErrors;

212

/** General submission error */

213

submitError?: any;

214

/** Whether the last submission failed */

215

submitFailed?: boolean;

216

/** Whether the last submission succeeded */

217

submitSucceeded?: boolean;

218

/** Whether form has validation errors */

219

hasValidationErrors?: boolean;

220

/** Whether form has submission errors */

221

hasSubmitErrors?: boolean;

222

}

223

224

type ValidationErrors = Record<string, any>;

225

type SubmissionErrors = Record<string, any>;

226

```

227

228

**Usage Example:**

229

230

```typescript

231

function ErrorHandlingForm() {

232

const onSubmit = async (values: any) => {

233

// Simulate server validation

234

if (values.email === "taken@example.com") {

235

return { email: "Email already taken" };

236

}

237

// Success case

238

console.log("Submitted:", values);

239

};

240

241

return (

242

<Form

243

onSubmit={onSubmit}

244

render={({ handleSubmit, submitError, hasSubmitErrors, errors }) => (

245

<form onSubmit={handleSubmit}>

246

{submitError && <div className="error">{submitError}</div>}

247

{hasSubmitErrors && (

248

<div className="error">Please fix the errors below</div>

249

)}

250

{/* form fields */}

251

</form>

252

)}

253

/>

254

);

255

}

256

```