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
Wir schreiben API für React-Komponenten, Teil 4: Vorsicht vor 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
Lassen Sie uns über die Avatar
Komponente sprechen.

<Avatar image="simons-cat.png" />
Avatare sind überall in Anwendungen zu finden und werden normalerweise in verschiedenen Größen angeboten. Sie benötigen einen großen Avatar für das Benutzerprofil, einen kleinen in den Dropdown-Listen und einige Zwischen-Avatare.

Fügen wir die Requisitengröße hinzu (Requisite für Größen).
Wir möchten dem Entwickler nicht die Möglichkeit geben, beliebige Breiten und Höhen anzugeben, sondern dem Entwickler mehrere mögliche Größen geben.

<Avatar size="xsmall" image="simons-cat.png" /> <Avatar size="small" image="simons-cat.png" /> <Avatar size="medium" image="simons-cat.png" /> <Avatar size="large" image="simons-cat.png" /> <Avatar size="xlarge" image="simons-cat.png" />
Im Kosmos haben wir immer noch Avatare für Apps. Wir möchten, dass sie etwas anders aussehen - ein abgerundetes Quadrat anstelle eines Kreises.
Ein Teil der Erstellung einer guten API besteht darin, Entwicklern die Möglichkeit zu geben, über Daten und nicht über Design nachzudenken. Das Design sollte sich bereits in der Komponente befinden
Wir können eine weitere Requisite hinzufügen, die zwischen zwei Arten von Avataren unterscheidet. Eine kleine Requisite kann nicht schaden, oder?

<Avatar type="user" image="simons-cat.png" /> <Avatar type="app" image="firebase.png" />
Sieht gut aus, nicht wahr?
Und ja, wir erhalten Unterstützung für mehrere Größen für den Anwendungsavatar, da es sich um dieselbe Komponente handelt. Im Allgemeinen brauchen wir das nicht, aber warum nicht, da es uns nichts gekostet hat

<Avatar type="app" size="xsmall" image="firebase.png" /> <Avatar type="app" size="small" image="firebase.png" /> <Avatar type="app" size="medium" image="firebase.png" /> <Avatar type="app" size="large" image="firebase.png" /> <Avatar type="app" size="xlarge" image="firebase.png" />
Lassen Sie uns darüber sprechen, wie der Entwickler diese Komponente tatsächlich in seiner Anwendung verwendet. Die Benutzerinformationen stammen wahrscheinlich aus der API und enthalten die URL des Avatars. Der Entwickler gibt diese Informationen mithilfe von Requisiten an die Avatar
Komponente weiter.
Und wenn der Benutzer noch keinen Avatar hochgeladen hat, möchten wir den Standardwert anzeigen. Gleiches gilt für das Anwendungslogo.

<Avatar type="user" image={props.user.avatar} /> <Avatar type="user" image={missing} /> <Avatar type="app" image={props.app.logo} /> <Avatar type="app" image={missing} />
Das Standardbild ist bereits in der Komponente enthalten, daher fragen wir den Entwickler nicht nach dem Standardbild.
Dies ist ein guter Fallback, aber wir können noch mehr tun.
Wir können die Initialen eines Benutzernamens mit einem eindeutigen Hintergrund anzeigen (Google Mail hat diese Vorlage populär gemacht, es hilft, schnell zwischen Personen zu unterscheiden).

<Avatar type="user" image={props.user.avatar} /> <Avatar type="user" image={missing} /> <Avatar type="user" initials={props.user.intials} image={missing} /> <Avatar type="app" image={props.app.logo} /> <Avatar type="app" image={missing} /> <Avatar type="app" icon={props.app.type} image={missing} />
Schauen wir uns alle Requisiten an, die unsere Komponente unterstützt:
Wir haben mit einer einfachen Avatar-Komponente begonnen, aber jetzt unterstützt sie all diese Requisiten und Verhaltensweisen!
Wenn Sie eine Komponente sehen, die viele Requisiten unterstützt, versucht sie wahrscheinlich, zu viele Dinge zu tun. Sie haben gerade Apropcalypse erstellt .
Dieses Konzept wurde von Jenn Creighton geprägt .
Wir versuchen, unsere Avatar
Komponente für Benutzer und Anwendungen funktionsfähig zu machen und gleichzeitig mit unterschiedlichen Größen und Optionen für das Fallback-Verhalten zu arbeiten.
Es ermöglicht auch seltsame Kombinationen, die für die Verwendung nicht empfohlen werden, z. B. einen Avatar für eine Sicherungstextanwendung. Denken Sie daran, dies war Tipp 1 - Erstellen Sie keine widersprüchlichen Requisiten (siehe Schreiben der API für React-Komponenten, Teil 1: Erstellen Sie keine widersprüchlichen Requisiten )!
Okay, wie gehen wir damit um? Erstellen Sie zwei verschiedene Komponenten.
Tipp:
Haben Sie keine Angst, eine neue Komponente zu erstellen, anstatt einer vorhandenen Komponente Requisiten und zusätzliche Logik hinzuzufügen.
Zunächst sieht die API für zwei verschiedene Avatar-Komponenten folgendermaßen aus:

<UserAvatar size="large" image="simons-cat.png" /> <UserAvatar size="large" image="" /> <UserAvatar size="large" fallback="LA" image="" /> <AppAvatar image="firebase.png" /> <AppAvatar image="" /> <AppAvatar fallback="database" image="" />
In dieser API sind einige Dinge zu beachten:
- In
AppAvatar
konnten unnötige Funktionen wie die size
AppAvatar
. - Wir haben die Größe unserer API reduziert, indem wir für beide Komponenten denselben
fallback
Namen (Fallback) beibehalten haben.
Erinnerst du dich an Tipp Nummer 2 in dieser Serie ? Wir möchten, dass Entwickler über Verhalten ( fallback
) und nicht über Interaktion / Implementierung (Initialen oder Symbole) nachdenken. Auf diese Weise lernen Entwickler APIs und Möglichkeiten zur schnelleren Verwendung von Komponenten. - Wir können auch widersprüchliche Requisiten vermeiden .
- Schließlich haben wir die Anzahl der Requisiten reduziert. Schauen Sie sich den Requisitentisch an, er ist viel sauberer geworden:
UserAvatar:
AppAvatar:
Das einzige, was mich an dieser API ein wenig aufregt, ist, dass obwohl beide Komponenten den gleichen Namen und Typ für fallback: string
(ein Fallback mit Typ string
ist ein String), einer von ihnen zwei Buchstaben für die Initialen benötigt, während Zeit wie eine andere ist der Name des Symbols.
Lassen Sie uns über die Implementierung sprechen. Es ist verlockend, eine BaseAvatar
Komponente zu erstellen, die sowohl UserAvatar
als auch AppAvatar
, während einige Requisiten blockiert werden.
function UserAvatar(props) { return ( <BaseAvatar image={props.image} type="user" initials={props.fallback} /> ) } render(<UserAvatar fallback="LA" />)
Und das ist überhaupt keine schlechte Idee. Aber es ist am Anfang ziemlich schwierig vorherzusagen, was wir brauchen könnten. Wir sagen zukünftige Anforderungen schlecht voraus.
Beginnen Sie mit zwei verschiedenen Komponenten, und während Sie sie entwickeln, können Sie ähnliche Muster erkennen und eine gute Abstraktion finden. Fehlende Abstraktion ist viel besser als falsche Abstraktion.
Vervielfältigung ist besser als falsche Abstraktion - Sandi Metz
Kehren Sie zu Ihrem Code zurück und suchen Sie die Komponente, die zu viele Requisiten benötigt, und prüfen Sie, ob Sie sie vereinfachen können, indem Sie sie in mehrere Komponenten aufteilen.
Für weitere Studien:
- ein Vortrag von Jenn Creighton , in dem sie über die Apropacalips spricht
- Sandi Metz Vortrag über Duplikate und Abstraktionen