TanStack Form bietet vollständige Flexibilität bei den Fehlertypen, die Sie von Validatoren zurückgeben können. Zeichenkettenfehler sind am gebräuchlichsten und am einfachsten zu handhaben, aber die Bibliothek erlaubt es Ihnen, jeden Werttyp von Ihren Validatoren zurückzugeben.
Als allgemeine Regel gilt: Jeder "truthy"-Wert wird als Fehler betrachtet und markiert das Formular oder Feld als ungültig, während "falsy"-Werte (false, undefined, null, etc.) bedeuten, dass kein Fehler vorliegt und das Formular oder Feld gültig ist.
<form.Field
name="username"
validators={{
onChange: ({ value }) =>
value.length < 3 ? 'Username must be at least 3 characters' : undefined,
}}
/>
<form.Field
name="username"
validators={{
onChange: ({ value }) =>
value.length < 3 ? 'Username must be at least 3 characters' : undefined,
}}
/>
Für formularweite Validierung, die mehrere Felder betrifft
const form = useForm({
defaultValues: {
username: '',
email: '',
},
validators: {
onChange: ({ value }) => {
return {
fields: {
username:
value.username.length < 3 ? 'Username too short' : undefined,
email: !value.email.includes('@') ? 'Invalid email' : undefined,
},
}
},
},
})
const form = useForm({
defaultValues: {
username: '',
email: '',
},
validators: {
onChange: ({ value }) => {
return {
fields: {
username:
value.username.length < 3 ? 'Username too short' : undefined,
email: !value.email.includes('@') ? 'Invalid email' : undefined,
},
}
},
},
})
Zeichenkettenfehler sind der häufigste Typ und werden leicht in Ihrer Benutzeroberfläche angezeigt
{
field.state.meta.errors.map((error, i) => (
<div key={i} className="error">
{error}
</div>
))
}
{
field.state.meta.errors.map((error, i) => (
<div key={i} className="error">
{error}
</div>
))
}
Nützlich zur Darstellung von Mengen, Schwellenwerten oder Größen
<form.Field
name="age"
validators={{
onChange: ({ value }) => (value < 18 ? 18 - value : undefined),
}}
/>
<form.Field
name="age"
validators={{
onChange: ({ value }) => (value < 18 ? 18 - value : undefined),
}}
/>
Anzeige in der Benutzeroberfläche
// TypeScript knows the error is a number based on your validator
<div className="error">
You need {field.state.meta.errors[0]} more years to be eligible
</div>
// TypeScript knows the error is a number based on your validator
<div className="error">
You need {field.state.meta.errors[0]} more years to be eligible
</div>
Einfache Flaggen zur Anzeige des Fehlerzustands
<form.Field
name="accepted"
validators={{
onChange: ({ value }) => (!value ? true : undefined),
}}
/>
<form.Field
name="accepted"
validators={{
onChange: ({ value }) => (!value ? true : undefined),
}}
/>
Anzeige in der Benutzeroberfläche
{
field.state.meta.errors[0] === true && (
<div className="error">You must accept the terms</div>
)
}
{
field.state.meta.errors[0] === true && (
<div className="error">You must accept the terms</div>
)
}
Umfangreiche Fehlerobjekte mit mehreren Eigenschaften
<form.Field
name="email"
validators={{
onChange: ({ value }) => {
if (!value.includes('@')) {
return {
message: 'Invalid email format',
severity: 'error',
code: 1001,
}
}
return undefined
},
}}
/>
<form.Field
name="email"
validators={{
onChange: ({ value }) => {
if (!value.includes('@')) {
return {
message: 'Invalid email format',
severity: 'error',
code: 1001,
}
}
return undefined
},
}}
/>
Anzeige in der Benutzeroberfläche
{
typeof field.state.meta.errors[0] === 'object' && (
<div className={`error ${field.state.meta.errors[0].severity}`}>
{field.state.meta.errors[0].message}
<small> (Code: {field.state.meta.errors[0].code})</small>
</div>
)
}
{
typeof field.state.meta.errors[0] === 'object' && (
<div className={`error ${field.state.meta.errors[0].severity}`}>
{field.state.meta.errors[0].message}
<small> (Code: {field.state.meta.errors[0].code})</small>
</div>
)
}
Im obigen Beispiel hängt es vom Ereignisfehler ab, den Sie anzeigen möchten.
Mehrere Fehlermeldungen für ein einzelnes Feld
<form.Field
name="password"
validators={{
onChange: ({ value }) => {
const errors = []
if (value.length < 8) errors.push('Password too short')
if (!/[A-Z]/.test(value)) errors.push('Missing uppercase letter')
if (!/[0-9]/.test(value)) errors.push('Missing number')
return errors.length ? errors : undefined
},
}}
/>
<form.Field
name="password"
validators={{
onChange: ({ value }) => {
const errors = []
if (value.length < 8) errors.push('Password too short')
if (!/[A-Z]/.test(value)) errors.push('Missing uppercase letter')
if (!/[0-9]/.test(value)) errors.push('Missing number')
return errors.length ? errors : undefined
},
}}
/>
Anzeige in der Benutzeroberfläche
{
Array.isArray(field.state.meta.errors) && (
<ul className="error-list">
{field.state.meta.errors.map((err, i) => (
<li key={i}>{err}</li>
))}
</ul>
)
}
{
Array.isArray(field.state.meta.errors) && (
<ul className="error-list">
{field.state.meta.errors.map((err, i) => (
<li key={i}>{err}</li>
))}
</ul>
)
}
Standardmäßig fasst TanStack Form Fehler aus allen Validierungsquellen (onChange, onBlur, onSubmit) zu einem einzigen `errors`-Array zusammen. Die Prop `disableErrorFlat` bewahrt die Fehlerquellen.
<form.Field
name="email"
disableErrorFlat
validators={{
onChange: ({ value }) =>
!value.includes('@') ? 'Invalid email format' : undefined,
onBlur: ({ value }) =>
!value.endsWith('.com') ? 'Only .com domains allowed' : undefined,
onSubmit: ({ value }) => (value.length < 5 ? 'Email too short' : undefined),
}}
/>
<form.Field
name="email"
disableErrorFlat
validators={{
onChange: ({ value }) =>
!value.includes('@') ? 'Invalid email format' : undefined,
onBlur: ({ value }) =>
!value.endsWith('.com') ? 'Only .com domains allowed' : undefined,
onSubmit: ({ value }) => (value.length < 5 ? 'Email too short' : undefined),
}}
/>
Ohne `disableErrorFlat` würden alle Fehler in `field.state.meta.errors` zusammengefasst werden. Mit ihr können Sie auf Fehler nach ihrer Quelle zugreifen.
{
field.state.meta.errorMap.onChange && (
<div className="real-time-error">{field.state.meta.errorMap.onChange}</div>
)
}
{
field.state.meta.errorMap.onBlur && (
<div className="blur-feedback">{field.state.meta.errorMap.onBlur}</div>
)
}
{
field.state.meta.errorMap.onSubmit && (
<div className="submit-error">{field.state.meta.errorMap.onSubmit}</div>
)
}
{
field.state.meta.errorMap.onChange && (
<div className="real-time-error">{field.state.meta.errorMap.onChange}</div>
)
}
{
field.state.meta.errorMap.onBlur && (
<div className="blur-feedback">{field.state.meta.errorMap.onBlur}</div>
)
}
{
field.state.meta.errorMap.onSubmit && (
<div className="submit-error">{field.state.meta.errorMap.onSubmit}</div>
)
}
Dies ist nützlich für
TanStack Form bietet starke Typsicherheit für die Fehlerbehandlung. Jeder Schlüssel in der `errorMap` hat genau den Typ, der von seinem entsprechenden Validator zurückgegeben wird, während das `errors`-Array einen Union-Typ aller möglichen Fehlerwerte von allen Validatoren enthält.
<form.Field
name="password"
validators={{
onChange: ({ value }) => {
// This returns a string or undefined
return value.length < 8 ? 'Too short' : undefined
},
onBlur: ({ value }) => {
// This returns an object or undefined
if (!/[A-Z]/.test(value)) {
return { message: 'Missing uppercase', level: 'warning' }
}
return undefined
},
}}
children={(field) => {
// TypeScript knows that errors[0] can be string | { message: string, level: string } | undefined
const error = field.state.meta.errors[0]
// Type-safe error handling
if (typeof error === 'string') {
return <div className="string-error">{error}</div>
} else if (error && typeof error === 'object') {
return <div className={error.level}>{error.message}</div>
}
return null
}}
/>
<form.Field
name="password"
validators={{
onChange: ({ value }) => {
// This returns a string or undefined
return value.length < 8 ? 'Too short' : undefined
},
onBlur: ({ value }) => {
// This returns an object or undefined
if (!/[A-Z]/.test(value)) {
return { message: 'Missing uppercase', level: 'warning' }
}
return undefined
},
}}
children={(field) => {
// TypeScript knows that errors[0] can be string | { message: string, level: string } | undefined
const error = field.state.meta.errors[0]
// Type-safe error handling
if (typeof error === 'string') {
return <div className="string-error">{error}</div>
} else if (error && typeof error === 'object') {
return <div className={error.level}>{error.message}</div>
}
return null
}}
/>
Die `errorMap`-Eigenschaft ist ebenfalls vollständig typisiert und entspricht den Rückgabetypen Ihrer Validierungsfunktionen.
// With disableErrorFlat
<form.Field
name="email"
disableErrorFlat
validators={{
onChange: ({ value }): string | undefined =>
!value.includes("@") ? "Invalid email" : undefined,
onBlur: ({ value }): { code: number, message: string } | undefined =>
!value.endsWith(".com") ? { code: 100, message: "Wrong domain" } : undefined
}}
children={(field) => {
// TypeScript knows the exact type of each error source
const onChangeError: string | undefined = field.state.meta.errorMap.onChange;
const onBlurError: { code: number, message: string } | undefined = field.state.meta.errorMap.onBlur;
return (/* ... */);
}}
/>
// With disableErrorFlat
<form.Field
name="email"
disableErrorFlat
validators={{
onChange: ({ value }): string | undefined =>
!value.includes("@") ? "Invalid email" : undefined,
onBlur: ({ value }): { code: number, message: string } | undefined =>
!value.endsWith(".com") ? { code: 100, message: "Wrong domain" } : undefined
}}
children={(field) => {
// TypeScript knows the exact type of each error source
const onChangeError: string | undefined = field.state.meta.errorMap.onChange;
const onBlurError: { code: number, message: string } | undefined = field.state.meta.errorMap.onBlur;
return (/* ... */);
}}
/>
Diese Typsicherheit hilft, Fehler zur Kompilierzeit statt zur Laufzeit zu erkennen, was Ihren Code zuverlässiger und wartbarer macht.
Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.