TanStack Form unterscheidet sich von den meisten Formularbibliotheken, die Sie bisher verwendet haben. Es wurde für den Einsatz in großen Produktionsumgebungen entwickelt, mit einem Fokus auf Typsicherheit, Leistung und Komposition für eine unübertroffene Entwicklererfahrung.
Infolgedessen haben wir eine Philosophie rund um die Verwendung der Bibliothek entwickelt, die Skalierbarkeit und langfristige Entwicklererfahrung über kurze und teilbare Code-Schnipsel stellt.
Hier ist ein Beispiel für ein Formular, das viele unserer Best Practices befolgt und es Ihnen ermöglicht, selbst hochkomplexe Formulare nach einer kurzen Einarbeitungszeit schnell zu entwickeln.
import React from 'react'
import ReactDOM from 'react-dom/client'
import { createFormHook, createFormHookContexts } from '@tanstack/react-form'
// Form components that pre-bind events from the form hook; check our "Form Composition" guide for more
import { TextField, NumberField, SubmitButton } from '~our-app/ui-library'
// We also support Valibot, ArkType, and any other standard schema library
import { z } from 'zod'
const { fieldContext, formContext } = createFormHookContexts()
// Allow us to bind components to the form to keep type safety but reduce production boilerplate
// Define this once to have a generator of consistent form instances throughout your app
const { useAppForm } = createFormHook({
fieldComponents: {
TextField,
NumberField,
},
formComponents: {
SubmitButton,
},
fieldContext,
formContext,
})
const PeoplePage = () => {
const form = useAppForm({
defaultValues: {
username: '',
age: 0,
},
validators: {
// Pass a schema or function to validate
onChange: z.object({
username: z.string(),
age: z.number().min(13),
}),
},
onSubmit: ({ value }) => {
// Do something with form data
alert(JSON.stringify(value, null, 2))
},
})
return (
<form
onSubmit={(e) => {
e.preventDefault()
form.handleSubmit()
}}
>
<h1>Personal Information</h1>
{/* Components are bound to `form` and `field` to ensure extreme type safety */}
{/* Use `form.AppField` to render a component bound to a single field */}
<form.AppField
name="username"
children={(field) => <field.TextField label="Full Name" />}
/>
{/* The "name" property will throw a TypeScript error if typo'd */}
<form.AppField
name="age"
children={(field) => <field.NumberField label="Age" />}
/>
{/* Components in `form.AppForm` have access to the form context */}
<form.AppForm>
<form.SubmitButton />
</form.AppForm>
</form>
)
}
const rootElement = document.getElementById('root')!
ReactDOM.createRoot(rootElement).render(<PeoplePage />)
import React from 'react'
import ReactDOM from 'react-dom/client'
import { createFormHook, createFormHookContexts } from '@tanstack/react-form'
// Form components that pre-bind events from the form hook; check our "Form Composition" guide for more
import { TextField, NumberField, SubmitButton } from '~our-app/ui-library'
// We also support Valibot, ArkType, and any other standard schema library
import { z } from 'zod'
const { fieldContext, formContext } = createFormHookContexts()
// Allow us to bind components to the form to keep type safety but reduce production boilerplate
// Define this once to have a generator of consistent form instances throughout your app
const { useAppForm } = createFormHook({
fieldComponents: {
TextField,
NumberField,
},
formComponents: {
SubmitButton,
},
fieldContext,
formContext,
})
const PeoplePage = () => {
const form = useAppForm({
defaultValues: {
username: '',
age: 0,
},
validators: {
// Pass a schema or function to validate
onChange: z.object({
username: z.string(),
age: z.number().min(13),
}),
},
onSubmit: ({ value }) => {
// Do something with form data
alert(JSON.stringify(value, null, 2))
},
})
return (
<form
onSubmit={(e) => {
e.preventDefault()
form.handleSubmit()
}}
>
<h1>Personal Information</h1>
{/* Components are bound to `form` and `field` to ensure extreme type safety */}
{/* Use `form.AppField` to render a component bound to a single field */}
<form.AppField
name="username"
children={(field) => <field.TextField label="Full Name" />}
/>
{/* The "name" property will throw a TypeScript error if typo'd */}
<form.AppField
name="age"
children={(field) => <field.NumberField label="Age" />}
/>
{/* Components in `form.AppForm` have access to the form context */}
<form.AppForm>
<form.SubmitButton />
</form.AppForm>
</form>
)
}
const rootElement = document.getElementById('root')!
ReactDOM.createRoot(rootElement).render(<PeoplePage />)
Obwohl wir im Allgemeinen empfehlen, createFormHook für weniger Boilerplate auf lange Sicht zu verwenden, unterstützen wir auch einmalige Komponenten und andere Verhaltensweisen mit useForm und form.Field.
import React from 'react'
import ReactDOM from 'react-dom/client'
import { useForm } from '@tanstack/react-form'
const PeoplePage = () => {
const form = useForm({
defaultValues: {
username: '',
age: 0,
},
onSubmit: ({ value }) => {
// Do something with form data
alert(JSON.stringify(value, null, 2))
},
})
return (
<form.Field
name="age"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value > 13 ? undefined : 'Must be 13 or older',
}}
children={(field) => (
<>
<input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
type="number"
onChange={(e) => field.handleChange(e.target.valueAsNumber)}
/>
{!field.state.meta.isValid && (
<em>{field.state.meta.errors.join(',')}</em>
)}
</>
)}
/>
)
}
const rootElement = document.getElementById('root')!
ReactDOM.createRoot(rootElement).render(<PeoplePage />)
import React from 'react'
import ReactDOM from 'react-dom/client'
import { useForm } from '@tanstack/react-form'
const PeoplePage = () => {
const form = useForm({
defaultValues: {
username: '',
age: 0,
},
onSubmit: ({ value }) => {
// Do something with form data
alert(JSON.stringify(value, null, 2))
},
})
return (
<form.Field
name="age"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value > 13 ? undefined : 'Must be 13 or older',
}}
children={(field) => (
<>
<input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
type="number"
onChange={(e) => field.handleChange(e.target.valueAsNumber)}
/>
{!field.state.meta.isValid && (
<em>{field.state.meta.errors.join(',')}</em>
)}
</>
)}
/>
)
}
const rootElement = document.getElementById('root')!
ReactDOM.createRoot(rootElement).render(<PeoplePage />)
Alle Eigenschaften von useForm können in useAppForm verwendet werden und alle Eigenschaften von form.Field können in form.AppField verwendet werden.
Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.