# Die Formspree React-Bibliothek

> Formspree Docs · Mit React arbeiten · 8. Januar 2026

## Installation

Diese Bibliothek setzt voraus, dass React bereits als Peer-Dependency in deiner Umgebung installiert ist. Unsere Helfer basieren auf [**React Hooks**](https://reactjs.org/docs/hooks-intro.html), daher **musst du Version 16.8.0 oder höher verwenden**.

```bash
npm install @formspree/react
```

[**Quellcode auf GitHub**](https://github.com/formspree/formspree-react) | **[npm-Paket](https://www.npmjs.com/package/@formspree/react)**  
  
Du kannst diese Bibliothek mit oder ohne das Formspree CLI verwenden. Dieser Artikel geht davon aus, dass du Formulare im Dashboard erstellst. Hilfe zu CLI-Projekten findest du in unserem Artikel zur Verwendung des [Formspree CLI](/articles/using-the-cli/the-formspree-cli/).

## Verwendung

Der `useForm`-[**React-Hook**](https://reactjs.org/docs/hooks-intro.html) ist der einfachste Weg, ein React-Formular mit Formspree einzurichten. Importiere einfach `@formspree/react` und rufe dann `useForm` mit der [hashid](/articles/the-forms-api/getting-your-form-s-hashid/) des Formulars auf, die du durch das Erstellen eines Formulars im Formspree-Dashboard erhältst. 

```jsx
import { useForm } from '@formspree/react';

function MyForm() {
  const [state, handleSubmit, reset] = useForm('{your-form-id}');
  if (state.succeeded) {
    return <div>Thank you for signing up!</div>;
  }
  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="email">Email</label>
      <input id="email" type="email" name="email" />
      <button type="submit" disabled={state.submitting}>Sign up</button>
    </form>
  )
}
```

## State-Objekt

Der erste Wert in dem von diesem Hook zurückgegebenen Array ist ein State-Objekt:

```jsx
const [state, handleSubmit, reset] = useForm('{your-form-id}');
```

Das State-Objekt enthält die folgenden Eigenschaften:

| Schlüssel | Beschreibung |
| --- | --- |
| `submitting` | Ein Boolean, der angibt, ob das Formular gerade übermittelt wird (Standardwert `false`) |
| `succeeded` | Ein Boolean, der angibt, ob das Formular erfolgreich übermittelt wurde (Standardwert `false`) |
| `errors` | Eine Instanz der Klasse `SubmissionError`, die serverseitige Validierungsfehler enthält (Standardwert `null`) |
| `result` | Ein Objekt mit einer Eigenschaft `next`, die die Weiterleitungs-URL ist, wenn die Übermittlung erfolgreich ist (Standardwert `null`) |

Der State ändert sich im Laufe der Zeit auf folgende Weise:

-   Wenn `handleSubmit` aufgerufen wird, wird `submitting` zu `true`
-   Wenn die Übermittlung die serverseitigen Validierungen nicht besteht, wird eine neue Instanz von `errors` mit den spezifischen Fehlern erstellt
-   Wenn die Übermittlung erfolgreich ist, wird `succeeded` zu `true` und `result` ist nicht `null`
-   Nachdem die Übermittlungsanfrage abgeschlossen ist, wird `submitting` immer zu `false`

Das `errors`-Objekt hat die folgenden Methoden:

| Schlüssel | Beschreibung |
| --- | --- |
| `getFormErrors()` | Gibt ein Array von Fehlern auf Formularebene zurück |
| `getFieldErrors(field)` | Gibt ein Array von Fehlern für das `field` zurück |
| `getAllFieldErrors()` | Gibt ein Array von Schlüssel-Wert-Paaren mit Fehlern auf Feldebene aller Felder zurück (`[field, errors][]`) |

Die Fehlerelemente im `errors`-Objekt haben die folgenden Eigenschaften:

| Schlüssel | Beschreibung |
| --- | --- |
| `message` | Ein menschenlesbares Fehlermeldungsfragment (z. B. "is required") |
| `code` | Ein maschinenfreundlicher Fehlercode (siehe [Fehlercodes](#errorcodes) unten) |
| `details` | Ein Objekt mit verschiedenen zusätzlichen Eigenschaften zum Fehler. Bei Verwendung mit Stripe enthält es beispielsweise ein Feld `stripeCode`, das den genauen Fehler von Stripe enthält |

## Reset

Der dritte Wert in dem vom Hook zurückgegebenen Array ist eine Reset-Funktion. 

```jsx
const [state, handleSubmit, reset] = useForm('{your-form-id}');
```

Diese Funktion wird verwendet, um das State-Objekt zurückzusetzen, nachdem eine Formularübermittlungsanfrage abgeschlossen wurde. Sie leert die Eigenschaften `result` und `errors` und setzt die Boolean-Eigenschaften `submitting` und `succeeded` auf ihren Standardzustand zurück (d. h. false). Du kannst diese Methode auf der Dankesseite verwenden, die du nach Abschluss der Formularübermittlungsanfrage anzeigst, damit der Benutzer das Formular zurücksetzen und erneut übermitteln kann.

Hier ist ein Beispiel, das zeigt, wie die Funktion `reset()` in einem Formular verwendet wird:

```jsx
function TestForm() {
    const [state, submit, reset] = useForm('{your-form-id}');

    if (state.submitting) {
        return <p>Submitting…</p>;
    }

    if (state.succeeded) {
        return (
            <div>
                <p>Thanks!</p>;<button onClick={reset}>Reset</button>
            </div>
        );
    }

    return (
        <div>
            <h1>Form</h1>
            <form onSubmit={submit}>
                <label htmlFor="email">Email</label>
                <input
                    id="email"
                    type="email"
                    name="email"
                    defaultValue="test@example.com"
                />

                <button type="submit">Sign up</button>

            </form>
        </div>
    );
}
```

## Validierungsfehler

Hier ist ein Beispielformular, das die Komponente `ValidationError` verwendet, um Feldfehler anzuzeigen:

```jsx
import { ValidationError, useForm } from '@formspree/react';

function MyForm() {
  const [state, handleSubmit] = useForm('{your-form-id}');
  if (state.succeeded) {
    return <div>Thank you for signing up!</div>;
  }
  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="email">Email</label>
      <input id="email" type="email" name="email" required />
      <ValidationError field="email" prefix="Email" errors={state.errors} />
      <button type="submit" disabled={state.submitting}>Sign up</button>
    </form>
  )
}
```

Die Komponente `ValidationError` akzeptiert die folgenden speziellen Eigenschaften:

-   `field` — der Name des Felds, für das Fehler angezeigt werden sollen. Wenn kein `field`-Attribut angegeben wird, werden allgemeine (nicht feldbezogene) Fehler gemeldet. (Siehe [Fehlercodes](#errorcodes) unten)
-   `errors` — das Objekt, das die Validierungsfehler enthält (erforderlich)
-   `prefix` — der benutzerfreundliche Name des Felds (optional, Standardwert "This field")

Alle anderen Props (wie `className`) werden an den `<div>`-Wrapper durchgereicht. Wenn das angegebene Feld ungültig ist, rendert diese Komponente ein `<div>`, das die Fehlermeldung enthält:

```jsx
<div {...props}>
  {prefix} {message}
</div>
```

## Zusätzliche Optionen

Dieser Hook akzeptiert zwei Argumente: den Formularschlüssel und ein Objekt, das Optionen enthält.

```jsx
const [state, handleSubmit, reset] = useForm('{your-form-key}', options);
```

Hier sind die zulässigen Optionen:

| Schlüssel | Typ | Beschreibung |
| --- | --- | --- |
| `data` | object | Ein Objekt, das Strings oder Funktionen enthält, die mit deinen Formulardaten zusammengeführt werden |
| `client` | Formspree | Eine Instanz des Formspree-Clients |

**Verwendungsbeispiel**

```jsx
const [state, handleSubmit, reset] = useForm('{your-form-id}', {
  data: {
    subject: 'Someone joined the newsletter',
    pageTitle: function() {
      // This function will be evaluated at submission time
      return document.title;
    }
  }
});
```

## Verwendung mit Stripe

Die Formspree React-Bibliothek bietet Unterstützung für Zahlungen über Stripe. Die Bibliothek übernimmt den größten Teil des Frontend-State-Managements, das für das Erstellen von Zahlungen und das Durchführen der [Strong Customer Authentication (SCA)](https://stripe.com/docs/strong-customer-authentication) erforderlich ist. Das Formspree-Backend kümmert sich dann um die Übermittlung der Zahlungen an Stripe. Zusammen reduziert Formspree den Entwicklungsaufwand für die Erstellung eines Zahlungsformulars erheblich.

Die Stripe-Funktionalität wird per Lazy Loading geladen. Das bedeutet, dass nur ein minimaler Stripe-Wrapper (nur 6k komprimiert) mit `@formspree/react` gebündelt wird. Der Großteil der Stripe-Bibliothek wird nur geladen, falls und wann Stripe-Elemente zum ersten Mal gerendert werden.

Um Stripe zu verwenden, umschließe zunächst deine App mit der Komponente `FormspreeProvider` und füge die Prop `stripePK` mit deinem öffentlichen Stripe-Schlüssel (publishable key) hinzu.

```jsx
import { FormspreeProvider } from '@formspree/react';

function MyApp() {
  return (
    <FormspreeProvider
      stripePK={'{your-stripe-publishable-key}'}
    >
      <PaymentForm />
    </FormspreeProvider>
  )
}
```

Verwende dann beim Erstellen deines Formulars die von `@formspree/react` exportierte Komponente `CardElement`. 

```jsx
import { useForm, CardElement, ValidationError } from '@formspree/react';

function PaymentForm() {
  const [state, handleSubmit] = useForm('{your-form-id}');

  if (state.succeeded) {
    return <div>Payment has been handled successfully!</div>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="email">Email</label>
        <input id="email" type="email" name="email" />
      </div>
      <div>
        <label>Card details</label>
        <CardElement />
        <ValidationError
          field="paymentMethod"
          errors={state.errors}
        />
      </div>
      <button type="submit" disabled={state.submitting}>
        {state.submitting ? 'Handling payment...' : 'Pay'}
      </button>
    </form>
  )
}
```

Die Komponente `CardElement` wird direkt von `@stripe/react-stripe-js` durchgereicht. Sie wird von Formspree React nur exportiert, um die Versionskonsistenz sicherzustellen. Die Dokumentation für die Komponente `CardElement` findest du [hier](https://stripe.com/docs/payments/accept-card-payments?platform=web&ui=elements&html-or-react=react#add-and-configure-a-component).

Beachte den Feldnamen "paymentMethod" bei `ValidationError`. Dies ist der Feldname, der zum Senden von Daten von Stripe an Formspree verwendet wird, und muss an `ValidationError` übergeben werden, um relevante Stripe-Fehler abzufangen.

## Verwendung mit einer externen Formularbibliothek

Der `useSubmit`-[**React-Hook**](https://reactjs.org/docs/hooks-intro.html) ist eine einfache Möglichkeit, eine andere Formularbibliothek mit Formspree zu integrieren. Importiere einfach `@formspree/react` und rufe dann `useSubmit` mit der [hashid](/articles/the-forms-api/getting-your-form-s-hashid/) des Formulars auf, die du durch das Erstellen eines Formulars im Formspree-Dashboard erhältst.

```tsx
import { useSubmit } from '@formspree/react';
import { useForm } from 'react-hook-form';

type Inputs = {
  email: string;
  message: string;
  name: string;
};

export function WithReactHookForm() {
  const {
    formState: { errors, isSubmitSuccessful, isSubmitting },
    handleSubmit,
    register,
    setError,
  } = useForm<Inputs>();

  const submit = useSubmit<Inputs>(
    process.env.REACT_APP_REACT_HOOK_FORM_ID as string,
    {
      onError(errs) {
        const formErrs = errs.getFormErrors();
        for (const { code, message } of formErrs) {
          setError(`root.${code}`, {
            type: code,
            message,
          });
        }

        const fieldErrs = errs.getAllFieldErrors();
        for (const [field, errs] of fieldErrs) {
          setError(field, {
            message: errs.map((e) => e.message).join(', '),
          });
        }
      },
    }
  );

  return (
    <div>
      {isSubmitSuccessful ? (
        <h2>Your message has been sent successfully!</h2>
      ) : (
        <form onSubmit={handleSubmit(submit)}>
          <div className="block">
            <label htmlFor="email">Email</label>
            <input {...register('email')} id="email" type="email" />
            {errors.email && <p className="error">{errors.email.message}</p>}
          </div>
          <div className="block">
            <label htmlFor="name">Name</label>
            <input {...register('name')} id="name" />
            {errors.name && <p className="error">{errors.name.message}</p>}
          </div>
          <div className="block">
            <label htmlFor="message">Message</label>
            <textarea {...register('message')} id="message" rows={10} />
          </div>
          {errors.root && (
            <div className="block">
              <ul className="error">
                {Object.values(errors.root).map((err) => {
                  if (typeof err !== 'object') {
                    return <li key={err}>{err}</li>;
                  }
                  const { type, message } = err;
                  return <li key={type}>{message}</li>;
                })}
              </ul>
            </div>
          )}
          <button type="submit" disabled={isSubmitting}>
            {isSubmitting ? 'Submitting...' : 'Submit'}
          </button>
        </form>
      )}
    </div>
  );
}
```

## Fehlercodes

Die folgenden Fehlercodes können im errors-Array des State-Objekts erscheinen:

| Code | Feldfehler | Beschreibung |
| --- | --- | --- |
| `INACTIVE` |   | Das Formular wurde deaktiviert |
| `BLOCKED` |   | Das Formular wurde blockiert |
| `EMPTY` |   | Es wurden keine Daten übermittelt |
| `PROJECT_NOT_FOUND` |   | Zum Übermitteln des Formulars wurde ein ungültiger Projektschlüssel verwendet |
| `FORM_NOT_FOUND` |   | Zum Übermitteln des Formulars wurde eine ungültige Formular-hashid verwendet |
| `NO_FILE_UPLOADS` |   | Datei-Uploads werden für dieses Formular nicht unterstützt |
| `TOO_MANY_FILES` |   | Das Formular wurde mit zu vielen Dateianhängen übermittelt |
| `FILES_TOO_BIG` |   | Eine oder mehrere hochgeladene Dateien überschreiten die maximale Dateigröße |
| `REQUIRED_FIELD_MISSING` | ✓ | Ein Feld ist erforderlich, aber es wurde kein Wert angegeben |
| `REQUIRED_FIELD_EMPTY` | ✓ | Ein Feld ist erforderlich, aber es wurde eine leere oder leerer String angegeben |
| `TYPE_EMAIL` | ✓ | Ein Feld sollte eine E-Mail enthalten |
| `TYPE_NUMERIC` | ✓ | Ein Feld sollte eine Zahl enthalten |
| `TYPE_TEXT` | ✓ | Ein Feld sollte Text enthalten |
| `STRIPE_CLIENT_ERROR` | ✓ | Stripe-Schlüssel fehlt |
| `STRIPE_SCA_ERROR` | ✓ | Stripe-SCA-Fehler. Siehe `details` |
