Schreiben einer API für React-Komponenten, Teil 1: Erstellen Sie keine widersprüchlichen Requisiten
Schreiben einer API für Reaktionskomponenten, Teil 2: Geben Sie dem Verhalten Namen, nicht der Interaktion
Schreiben einer API für React-Komponenten, Teil 3: Die Reihenfolge der Requisiten ist wichtig
Schreiben einer API für React Components, Teil 4: Vorsicht vor der Apropacalypse!
Schreiben einer API für Reaktionskomponenten, Teil 5: Verwenden Sie einfach die Komposition
Wir schreiben API für React-Komponenten, Teil 6: Wir erstellen die Kommunikation zwischen Komponenten
Sprechen wir über Formulare.
Höchstwahrscheinlich lesen Sie eine Reihe von Artikeln über die state
in Formularen, aber dies ist keiner dieser Artikel. Stattdessen möchte ich darüber sprechen, wie Formulare und ihre APIs funktionieren.

Hier ist viel los, schauen Sie sich die API an
<Form layout="label-on-left"> <Form.Field label="Name"> <TextInput type="text" placeholder="Enter your name" /> </Form.Field> <Form.Field label="Email"> <TextInput type="email" placeholder="email@domain.com" /> </Form.Field> </Form>
Schauen wir uns die einzelnen Komponenten an und analysieren sie:
Alles beginnt mit der Form
, die das grundlegende Formularelement mit einer angehängten Klasse ist. Es wird alles gerendert, was Sie hineingesteckt haben.
function Form(props) { return <form className="form">{props.children}</form> } render(<Form layout="label-on-left">...</Form>)
Es akzeptiert auch das Requisitenlayout, was nützlich ist, wenn Sie wenig Platz haben.

<Form layout="label-on-top">...</Form>
Dies ändert die Ausrichtung der Beschriftungen (von rechts nach links) und die Funktionsweise des margin
.
Das Formular kontrolliert nicht die Breite und den margin
seines internen Inhalts. Dies betrifft bereits das Eingabefeld in diesem Formular.
Daher sollte die Form
die folgenden layout
melden.
Der einfachste Weg wäre, das layout
mit Requisiten zu übergeben. Der Inhalt des Formulars ist jedoch dynamisch (vom Entwickler festgelegt, der dieses Formular verwendet). Wir wissen nicht genau, wie das Formular aussehen wird.
Hier hilft uns die Kontext-API.
const LayoutContext = React.createContext() function Form(props) { return ( <form className="form"> <LayoutContext.Provider value={{ layout: props.layout }} > {props.children} </LayoutContext.Provider> </form> ) } export default Form export { LayoutContext }
Jetzt kann das Formularfeld diesen Kontext verwenden und den layout
abrufen
Die FormField
Komponente (Formulareingabefeld) fügt FormField
eingegebenen FormField
eine label
hinzu (z. B. Texteingabe).
function Field(props) { return ( <div className="form-field"> <label {...props}>{props.label}</label> {props.children} </div> ) }
Darüber hinaus fügt er eine Klasse für das layout
die aus dem Kontext stammt, den wir in der Form
.
import { LayoutContext } from './form' function Field(props) { return ( <LayoutContext.Consumer> {context => ( <div className={`form-field ${context.layout}`}> <label {...props}>{props.label}</label> {props.children} </div> )} </LayoutContext.Consumer> ) }
React 16.8+ useContext-Hook erleichtert die Syntax
import { LayoutContext } from './form' function Field(props) { const context = useContext(LayoutContext) return ( <div className={`form-field ${context.layout}`}> <label {...props}>{props.label}</label> {props.children} </div> ) }
Wenn Sie interessiert sind, ist hier der CSS-Code:
.form-field.label-on-left { max-width: 625px; display: flex; align-items: center; } .form-field.label-on-left label { text-align: right; width: 175px; margin-right: 25px; } .form-field.label-on-top { width: 100%; display: block; } .form-field.label-on-top label { text-align: left; margin-bottom: 25px; }
Das letzte Detail, über das ich sprechen möchte, ist diese seltsam gepunktete Syntax für Komponenten.
Da Field
(das Eingabefeld) immer mit einem Formular verwendet wird, ist es sinnvoll, sie zu gruppieren.
Eine Möglichkeit, dies zu tun, besteht darin, es aus derselben Datei zu exportieren:
import Field from './field' function Form(props) { } export default Form export { Field }
Und jetzt können Benutzer sie zusammen importieren:
import Form, { Field } from 'components/form' render( <Form> <Field>...</Field> </Form> )
Wir können eine kleine Verbesserung vornehmen, indem wir Field
an die Komponente des Formulars anhängen.
import Field from './field' function Form(props) { } Form.Field = Field export default Form
Dieser Code funktioniert, da React-Komponenten Javascript-Objekte sind und Sie diesen Objekten zusätzliche Schlüssel hinzufügen können.
Für den Benutzer bedeutet dies, dass er beim Importieren eines Form
automatisch ein Field
erhält.
import Form from 'components/form' render( <Form> <Form.Field>...</Form.Field> </Form> )
Ich mag diese API sehr, sie macht die Verbindung zwischen Form
und Form.Field
offensichtlich.
Hinweis: Sie müssen den Kontext in eine andere Datei verschieben, um eine zirkuläre Abhängigkeit zu vermeiden.
Die Kombination von Syntax mit Punkten und Kontext macht unsere Form
intelligent und behält gleichzeitig ihre Funktionsfähigkeit für Kompositionen (Composite) bei.