Haben Sie schon einmal eine Formularvalidierung in React implementiert? Dann haben Sie höchstwahrscheinlich schon von React Hook Form gehört.
Die meisten Softwareprodukte enthalten heutzutage Formulare zum Übermitteln von Benutzerdaten. Es gibt verschiedene Bibliotheken für React, die uns helfen, die Benutzererfahrung zu verbessern: Formik, React Hook Form, Final Form usw. Sie erleichtern die Validierung und verbessern dabei auch die Benutzererfahrung.
Heute widmen wir uns der React Hook Form (react-hook-form) . Die Bibliothek bietet viele Vorteile: Sie hilft uns, gut aussehende und schnelle Formulare zu erstellen, reduziert das Rendering, verbessert die Benutzererfahrung und vieles mehr.
Beginnen wir mit einer kurzen technischen Einführung.
Eines der wichtigsten Konzepte von React Hook Form ist das Register – Sie sollten alle Ihre Komponenten registrieren, um deren Werte sowohl für das Formular als auch für die Übermittlung verfügbar zu machen.
Ein weiterer wichtiger Punkt ist, dass die Bibliothek Referenzen anstatt Props verwendet, um diese Werte mit den Komponenten zu teilen, was das Rendering reduziert.
Darüber hinaus gibt es sehr gute Dokumentationen, einschließlich vieler verschiedener Beispiele. Beispielsweise wird in diesem Video erklärt, wie man mit React Hook Form hochgeladene Dateien verarbeitet.
In diesem Blogbeitrag werden wir uns darauf konzentrieren, ein Formular zum Hochladen von Dateien zu erstellen – aber mit einer benutzerfreundlicheren User-Erfahrung als im obigen Beispiel. Wir werden Material-UI-Komponenten verwenden, aber Sie können beliebige andere Komponenten/Bibliotheken verwenden, die Sie bevorzugen.
Das Formular, das wir erstellen werden, ist ein einfaches mit ein paar Feldern: Name, Alter, E-Mail, Stadt, Profilbild und Dokumente.

Das Hinzufügen von Validierungen zu den Feldern ist eine einfache Aufgabe. Dazu müssen wir die gewünschte Validierung im Register des Formulars angeben. Weitere Details zur Validierung finden Sie in der Dokumentation unter https://react-hook-form.com/ .
Für unser Beispiel fügen wir die folgenden Validierungen hinzu:
- Name – soll erforderlich sein
- Alter – soll erforderlich und eine Ganzzahl zwischen 18 und 65 sein
- E-Mail – soll erforderlich sein und die Standard-E-Mail-Validierung "text@domain" erfüllen
- Stadt – soll erforderlich sein
All diese Validierungen werden als Eigenschaften im Register des Formulars übergeben. Zusätzlich zu jedem Feld können wir Fehlermeldungen angeben, um die UX zu verbessern.
<TextField
{...register("age", { required: true, min: 18, max: 65 })}
required
label="Age"
type="number"
variant="outlined"
error={!!errors.age}
/>
{errors.age && errors.age.type === "required" && (
<Alert severity="error">This field is required.</Alert>
)}
{errors.age && ["min", "max"].includes(errors.age.type) && (
<Alert severity="error">
You must be older than 18 and younger than 65 years old.
</Alert>
)}
Nun kommen wir zum interessanten Teil, nämlich der Umgang mit hochgeladenen Dateien. Zuerst erstellen wir eine Funktionalität zum Hochladen eines Profilbildes. Die Daten der hochgeladenen Datei werden im < input type=type"file" >Element gespeichert, aber wie wir wissen, sieht die Standardansicht dieses Elements sehr schlicht und wenig benutzerfreundlich aus.

Hier ist unser Plan wie wir bessere UX erzielen können:
- Verwenden Sie unsere eigene Komponente anstatt <input> .
- Verbinden Sie die Komponente mit dem Eingabefeld.
- Fügen Sie die hochgeladene Datei zum Formularzustand hinzu (oder verbinden Sie das Eingabefeld mit dem Formular "register").
- Fügen Sie eine Vorschau der hochgeladenen Datei hinzu.
Folgen wir unserem Plan und verstecken das Standard-Eingabefeld mit CSS. Unsere HiddenInput-Komponente hat die Eigenschaft „display: none“ angewendet. Dann fügen wir eine Button-Komponente aus dem Material-UI hinzu und verbinden beide über die Referenz hiddenInputReference. Um die hochgeladene Datei im Formularzustand zu behalten, fügen wir das HiddenInput-Feld auch über das Register in das Formular ein.
Hier wird es interessant – die React Hook Form Bibliothek verwaltet den Zustand des Formulars mithilfe von Referenzen. Normalerweise passiert dies automatisch, wenn Sie die register-Eigenschaft auf das Feld setzen (wie wir es für Name, Alter usw. getan haben). Um die Verbindung zwischen dem Button und dem HiddenInput aufrechtzuerhalten, während das HiddenInput gleichzeitig im Formularzustand registriert bleibt, müssen wir beide Referenzen – die hiddenInputRef und die registerRef – übergeben. Auf diese Weise wird beim Klicken auf den Button das HiddenInput ausgelöst und der Benutzer kann die Datei hochladen. Sobald die Datei hochgeladen ist, wird sie dem Formularzustand hinzugefügt.
Um die Funktionalität des Profilbildes abzuschließen, fügen wir eine Vorschau- und eine Avatar-Komponente hinzu, um es anzuzeigen.
const ProfilePicture = ({ register }) => {
const hiddenInputRef = useRef();
const [preview, setPreview] = useState();
const { ref: registerRef, ...rest } = register("profilePicture");
const handleUploadedFile = (event) => {
const file = event.target.files[0];
const urlImage = URL.createObjectURL(file);
setPreview(urlImage);
};
const onUpload = () => {
hiddenInputRef.current.click();
};
const uploadButtonLabel =
preview ? "Change image" : "Upload image";
return (
<ProfilePictureContainer>
<Label>Profile picture</Label>
<HiddenInput
type="file"
name="profilePicture"
{...rest}
onChange={handleUploadedFile}
ref={(e) => {
registerRef(e);
hiddenInputRef.current = e;
}}
/>
<Avatar src={preview} sx={{ width: 80, height: 80 }} />
<Button variant="text" onClick={onUpload}>
{uploadButtonLabel}
</Button>
</ProfilePictureContainer>
);
};
Jetzt wissen wir, wie man eine einzelne Datei bearbeitet. Aber was, wenn wir mehrere Dateien hochladen möchten? React Hook Form bietet eine einfache Lösung durch den useFieldArray-Hook. Dieser Hook wird verwendet, wenn Sie Arrays von Daten verwalten möchten. Der Ablauf ist dem oben beschriebenen ziemlich ähnlich – wir verwenden ein HiddenInput, das mehrere Dateien zulässt, eine Button-Komponente für eine bessere UX und die hiddenFileInput-Referenz, die beide miteinander verbindet.
Um es noch interessanter zu machen, fügen wir eine Funktion hinzu, die es uns ermöglicht, Dateien zu löschen, falls wir aus Versehen die falschen hochgeladen haben.
Zuerst zeigen wir die Dateinamen mit der Grid-Komponente an und fügen die DeleteForeverIcon-Schaltfläche hinzu, um eine hochgeladene Datei zu löschen. Wenn die Komponente, die wir verwenden (Grid), die Eingabereferenz nicht exponiert, sollten wir die Controller-Komponente von React Hook Form verwenden, die sich um den Registrierungsprozess kümmert.
const Documents = ({ control }) => {
const { fields, append, remove } = useFieldArray({
control,
name: "documents",
keyName: "documentId"
});
const hiddenFileInput = useRef(null);
const onAddDocuments = () => {
hiddenFileInput.current.click();
};
const handleAddDocuments = (event) => {
const uploadedFiles = Array.from(event.target.files);
const files = uploadedFiles.map((file) => ({
file
}));
append(files);
hiddenFileInput.current.value = "";
};
return (
<>
<HiddenInput
ref={hiddenFileInput}
type="file"
multiple
onChange={handleAddDocuments}
/>
<Box sx={{ m: 2, width: 300 }}>
<Label>Documents</Label>
{fields.map(({ documentId, file }, index) => (
<div key={documentId}>
<Controller
control={control}
name={`documents.${index}`}
render={() => (
<Grid container alignItems="center">
<Grid item xs={10}>
{file.name}
</Grid>
<Grid item xs={2}>
<IconButton
aria-label="Remove"
onClick={() => remove(index)}
>
<DeleteForeverIcon />
</IconButton>
</Grid>
</Grid>
)}
/>
</div>
))}
<Button variant="text" onClick={onAddDocuments}>
Add documents
</Button>
</Box>
</>
);
};
Im Endeffekt haben wir ein schön aussehendes Formular mit angewendeter Validierung und der Option, Dateien hochzuladen.
Hier ist der vollständige Code vom Beispiel: https://codesandbox.io/s/musing-villani-xdhobm. Natürlich können Sie beliebige Komponenten verwenden, denken Sie nur daran, sie im Register bekannt zu machen.
Insgesamt ist die React Hook Form Bibliothek eine ausgezeichnete Wahl, wenn Sie gut aussehende Formulare mit großartiger UX haben möchten. Die Bibliothek ist gut gepflegt und hat eine detaillierte Dokumentation.
