Hier ist eine Kartenkomponente in React
const Card = props => {
return(
<div className="card">
<h2>{props.title}</h2>
<p>{props.content}</p>
</div>
)
}
Das könnte ziemlich nützlich sein! Wenn Sie dieses Ding Hunderte Male verwenden, haben Sie jetzt die Möglichkeit, ein wenig HTML in Ihrer gesamten App ganz einfach zu refaktorieren. Diese Möglichkeit haben Sie bereits in CSS wegen des Klassennamens, aber jetzt haben Sie auch die HTML-Kontrolle. Fühlen Sie es.
Aber warten Sie. Vielleicht schränkt das ein… ein <h2>? Was, wenn das in einigen Verwendungszwecken eigentlich ein <h4> hätte sein sollen? Wie geht man damit um? Vielleicht eine Art API?
const Card = props => {
return(
<div className="card">
{props.type === "big" && <h2>{props.title}</h2>}
{props.type !== "big" && <h4>{props.title}</h4>}
<p>{props.content}</p>
</div>
)
}
Oder vielleicht erzwingen wir, dass eine Ebene übergeben wird?
const Card = props => {
const HeaderTag = `h${props.level}`;
return(
<div className="card">
<HeaderTag>{props.title}</HeaderTag>
<p>{props.content}</p>
</div>
)
}
Oder vielleicht ist diese Kopfzeile eine eigene Komponente?
Und eine erzwungene Absatz-Tag-Hülle um diesen Inhalt? Das ist ein wenig einschränkend, nicht wahr? Vielleicht sollte das ein <div> sein, damit es beliebige HTML-Inhalte aufnehmen kann, wie z. B. mehrere Absätze.
const Card = props => {
return(
<div className="card">
<WhateverHeader>{props.title}</WhateverHeader>
<div>{props.content}</div>
</div>
)
}
Eigentlich, warum überhaupt nach Inhalt mit Props fragen? Es ist wahrscheinlich einfacher, mit einer untergeordneten Komponente umzugehen, besonders wenn das, was übergeben wird, HTML ist.
const Card = props => {
return(
<div className="card">
<WhateverHeader>{props.title}</WhateverHeader>
{children}
</div>
)
}
Es gibt noch mehr Annahmen, die wir in Frage stellen könnten. Wie die Karte nur für einen Klassennamen… sollte das nicht flexibler sein?
const Card = props => {
const classes = `card ${props.className}`;
return(
<div className={classes}>
<WhateverHeader>{props.title}</WhateverHeader>
{children}
</div>
)
}
Ich erzwinge dort immer noch card. Wir könnten das weglassen, damit es nicht angenommen wird, oder einen weiteren Aspekt der Karten-API aufbauen, der eine Möglichkeit bietet, sich davon abzumelden.
Selbst die <div>-Hülle ist anmaßend. Vielleicht könnte dieser Tag-Name übergeben werden, damit Sie ihn in ein <section> oder <article> oder was auch immer Sie wollen, umwandeln können.
Vielleicht ist es besser, überhaupt nichts anzunehmen, und unsere Karte so zu gestalten
const Card = () => {
return(
<>
{children}
</>
)
}
Auf diese Weise haben Sie die Freiheit, alles zu ändern, was Sie ändern möchten. Zumindest ist es dann Flexibilität, während man entspannt damit umgeht, anstatt dieser Art von „Flexibilität“
<Card
parentTag="article"
headerLevel="3"
headerTitle="My Card"
contentWrapper="div"
cardVariation="extra-large"
contentContent=""
this=""
little=""
piggy=""
went=""
to=""
market=""
/>
Diese Art von extremer API-Erstellung passiert manchmal, wenn man gleichzeitig nach Kontrolle und Flexibilität strebt.
Ein Komponentenmodell ohne Anleitung kann auch zu Überkomponentisierung führen, wie vielleicht
const Card = props => {
return(
<CardWrapperTheme>
<CardWrapper>
<CardTitle />
<CardContent />
<CardFooter />
</CardWrapper>
</CardWrapperTheme>
)
}
Es kann vollkommen gute Gründe dafür geben, oder es kann das Ergebnis einer Komponentisierung sein, weil sie „kostenlos“ ist und sich einfach so anfühlt, wie es in einer Architektur, die dies unterstützt, gemacht wird.
Es gibt ein Gleichgewicht. Wenn eine Komponente zu streng ist, läuft sie Gefahr, dass die Leute sie nicht verwenden, weil sie ihnen nicht das geben, was sie brauchen. Und wenn sie zu locker ist, werden die Leute sie vielleicht nicht verwenden, weil sie keinen Wert bietet, und selbst wenn sie sie verwenden würden, bieten sie keine Kohäsion.
Ich habe hier keine Antworten, ich finde es einfach faszinierend.
Ich finde, der letzte Weg ist viel besser. Er bietet eine viel bessere Komposition. Sie können Prop-Forwarding und Ref-Forwarding durchführen. Es wurde „Compound Components“ genannt – mit anderen Worten, ein React-Element ist nicht als eigenständig gedacht, sondern wird kollektiv zusammengesetzt, um eine Sache zu ergeben – eine Karte. Für komplexere Komponenten mit internem Zustand können Sie Kontext verwenden, um Dinge weiterzugeben. Für die Hülle und die Unfähigkeit zu entscheiden, ob es sich um ein div oder etwas anderes handeln soll, ist das entstehende Muster ein
as-Prop, der wie folgt verwendet wirdEs gibt noch viel mehr zu beachten, aber wenn man alles zusammenzählt, ist diese Compound-Components-Strategie wirklich die beste für den Bau von Dingen wie dieser, finde ich. Dies ist keine Marketingveranstaltung, aber dies ist, was wir für Reach tun: https://gist.github.com/ryanflorence/e5c794e6093d16a69fa88d2112a292f7#one-to-one-rendered-dom-element-to-reach-component. Es ist erwähnenswert, dass die Leute, die den Begriff Compound Components geprägt haben, auch diejenigen sind, die Reach machen (und ich arbeite auch mit ihnen zusammen, nur zur vollständigen Transparenz)
Nein, Einfachheit ist immer am besten. Wenn ich eine Kartenkomponente hinzufüge, erwarte ich, nur eine Kartenkomponente zu importieren. Ich werde nicht cardheader, cardbody, cardwhatever importieren, wenn alles, was es tut, ein div ist, das ein div ausgibt.
Wenn etwas so anders ist, dass es eine Milliarde Unterkomponenten benötigt, dann ist es eine andere Komponente, Punkt.
IST ES ! (faszinierend).
Vielen Dank für diesen großartigen Beitrag.
Die Version direkt vor „ Ich erzwinge dort immer noch card “ ist meiner Meinung nach diejenige, die dem richtigen Kompromiss am nächsten kommt.
Ja, dem würde ich zustimmen (obwohl andere Lösungen je nach Situation besser sein könnten). Ich habe bei der Erstellung einiger verschachtelter serverseitig gerenderter Gutenberg-Blöcke für ein Projekt kürzlich im Grunde genau das mit Twig-Vorlagen gemacht. Es bietet ein gutes Maß an Flexibilität mit innerBlocks und dem standardmäßig bereitgestellten block className-Attribut.
Ich habe noch nie mit React gearbeitet, daher kann ich nichts zu den tatsächlichen Beispielen sagen… aber ich habe das Gefühl, dass dies etwas ist, mit dem ich mich oft bei CSS beschäftige.
Bei der Entwicklung eines UI-Elements stellt sich immer die Frage, wo die Grenze zwischen „Das ist flexibel genug, um in verschiedenen Bereichen wiederverwendet zu werden“ und „Das ist nur die Deklaration von 27.000 [Einfügen des Frameworks hier] Klassen“ liegt.
Betrachten Sie zum Beispiel Bootstrap….
Das ist deren ‚Card‘-Komponente. Sie könnten jedoch etwas Äußerst Ähnliches erstellen, indem Sie nur deren Hilfs- oder Utility-Klassen verwenden
Perfekt funktional und wahrscheinlich eine großartige Möglichkeit, zu lernen, wie man diese Utility-Klassen optimal nutzt. Aber es ist auch so abstrakt, dass es aufhört, eine Komponente zu sein, und zu einem bloßen Flickenteppich wird.
Was ist mit der Erstellung von „AbstractCard“, die alle erdenklichen Einstellungen hat, und dann die Erstellung einfacher, meistgenutzter Komponenten mit wenigen Einstellungen, die AbstractCard intern verwendet?
Dann kann der Benutzer entscheiden, ob er eine sehr einfache oder eine konfigurierbare Komponente verwenden möchte.