Wir schreiben API für React-Komponenten, Teil 6: Wir erstellen die Kommunikation zwischen Komponenten

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.


Etikett links


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:


Formular


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.


Label-on-Top-Telefon


 <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) { /*     `Provider`       */ 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


Formularfeld


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 .


 /*   layout */ import { LayoutContext } from './form' /*           -     API (Render Prop API)         */ 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


 /*   layout */ import { LayoutContext } from './form' function Field(props) { /*    useContext          */ 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; /*  flex*/ } .form-field.label-on-top label { text-align: left; /*  right */ margin-bottom: 25px; /*  margin-right */ } 

Form.Field?


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:


 /* form.js */ 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.


 /* form.js */ 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.

Source: https://habr.com/ru/post/de459422/


All Articles