Die Webentwicklung verändert sich ständig. Ein bestimmter Trend ist in letzter Zeit sehr populär geworden und widerspricht grundlegend der gängigen Meinung darüber, wie eine Webseite erstellt werden sollte. Für die einen ist es aufregend, für die anderen frustrierend, und die Gründe dafür sind schwer zu erklären.
Eine Webseite besteht traditionell aus drei separaten Teilen mit getrennten Zuständigkeiten: HTML-Code definiert die Struktur und Bedeutung des Inhalts auf einer Seite, CSS-Code definiert sein Aussehen und JavaScript-Code definiert sein Verhalten. In Teams mit engagierten Designern, HTML/CSS-Entwicklern und JavaScript-Entwicklern passt diese Trennung der Belange gut zu den Jobrollen: Designer bestimmen die visuellen Elemente und Benutzerinteraktionen auf einer Seite, HTML- und CSS-Entwickler reproduzieren diese visuellen Elemente in einem Webbrowser, und JavaScript-Entwickler fügen die Benutzerinteraktion hinzu, um alles miteinander zu verbinden und „zum Laufen zu bringen“. Man kann an einem Teil arbeiten, ohne sich mit allen dreien befassen zu müssen.
In den letzten Jahren haben JavaScript-Entwickler erkannt, dass sie durch die Definition der Seitenstruktur in JavaScript statt in HTML (mithilfe von Frameworks wie React) die Entwicklung und Wartung von Code für Benutzerinteraktionen vereinfachen können, der andernfalls viel komplexer zu erstellen wäre. Wenn man jemandem sagt, dass das von ihm geschriebene HTML zerstückelt und mit JavaScript vermischt werden muss, von dem er nichts versteht, kann er (verständlicherweise) frustriert werden und anfangen zu fragen, was zum Teufel wir davon haben.
Als JavaScript-Entwickler in einem funktionsübergreifenden Team bekomme ich diese Frage gelegentlich gestellt und habe oft Schwierigkeiten, sie zu beantworten. Alle Materialien, die ich zu diesem Thema gefunden habe, sind für ein Publikum geschrieben, das bereits mit JavaScript vertraut ist – was für diejenigen, die sich auf HTML und CSS konzentrieren, nicht besonders nützlich ist. Aber dieses HTML-in-JS-Muster (oder etwas anderes, das die gleichen Vorteile bietet) wird wahrscheinlich noch eine Weile existieren, daher halte ich es für wichtig, dass jeder, der an der Webentwicklung beteiligt ist, es versteht.
Dieser Artikel enthält Codebeispiele für Interessierte, aber mein Ziel ist es, dieses Konzept so zu erklären, dass es auch ohne sie verstanden werden kann.
Hintergrund: HTML, CSS und JavaScript
Um die Zielgruppe dieses Artikels so breit wie möglich zu fassen, möchte ich einen kurzen Überblick über die Arten von Code geben, die an der Erstellung einer Webseite beteiligt sind, und ihre traditionellen Rollen. Wenn Sie damit Erfahrung haben, können Sie diesen Teil überspringen.
HTML ist für Struktur und semantische Bedeutung
HTML (HyperText Markup Language) Code definiert die Struktur und Bedeutung des Inhalts auf einer Seite. Zum Beispiel enthält das HTML dieses Artikels den Text, den Sie gerade lesen, die Tatsache, dass er sich in einem Absatz befindet, und die Tatsache, dass er nach einer Überschrift und vor einem CodePen kommt.
Nehmen wir an, wir wollen eine einfache Einkaufslisten-App erstellen. Wir könnten mit etwas HTML wie diesem beginnen
Wir können diesen Code in einer Datei speichern, ihn in einem Webbrowser öffnen, und der Browser zeigt das gerenderte Ergebnis an. Wie Sie sehen, stellt der HTML-Code in diesem Beispiel einen Abschnitt einer Seite dar, der eine Überschrift „Shopping List (2 items)“, ein Texteingabefeld, eine Schaltfläche „Add Item“ und eine Liste mit zwei Elementen „Eggs“ und „Butter“ enthält. Auf einer traditionellen Website würde ein Benutzer zu einer Adresse in seinem Webbrowser navigieren, dann würde der Browser dieses HTML von einem Server anfordern, laden und anzeigen. Wenn sich bereits Elemente in der Liste befinden, könnte der Server HTML liefern, in dem die Elemente bereits vorhanden sind, wie in diesem Beispiel.
Versuchen Sie, etwas in das Eingabefeld einzugeben und auf die Schaltfläche „Add Item“ zu klicken. Sie werden feststellen, dass nichts passiert. Die Schaltfläche ist nicht mit Code verbunden, der das HTML ändern kann, und das HTML kann sich nicht selbst ändern. Dazu kommen wir gleich.
CSS ist für das Aussehen
CSS (Cascading Style Sheets) Code definiert das Aussehen einer Seite. Zum Beispiel enthält das CSS dieses Artikels die Schriftart, den Abstand und die Farbe des Textes, den Sie lesen.
Vielleicht ist Ihnen aufgefallen, dass unser Einkaufslistenbeispiel sehr schlicht aussieht. Es gibt keine Möglichkeit für HTML, Dinge wie Abstände, Schriftgrößen und Farben festzulegen. Hier kommt CSS (Cascading Style Sheets) ins Spiel. Auf derselben Seite wie das obige HTML könnten wir CSS-Code hinzufügen, um die Dinge ein wenig zu stylen
Wie Sie sehen können, hat dieses CSS die Schriftgrößen und -stärken geändert und dem Abschnitt eine schöne Hintergrundfarbe gegeben (Designer, bitte nicht @ mich; ich weiß, dass das immer noch hässlich ist). Ein Entwickler kann solche Stilregeln schreiben, und sie werden konsistent auf jede HTML-Struktur angewendet: Wenn wir dieser Seite weitere <section>-, <button>- oder <ul>-Elemente hinzufügen, werden dieselben Schriftänderungen angewendet.
Die Schaltfläche tut jedoch immer noch nichts: Hier kommt JavaScript ins Spiel.
JavaScript ist für das Verhalten
JavaScript-Code definiert das Verhalten interaktiver oder dynamischer Elemente auf einer Seite. Zum Beispiel werden die eingebetteten CodePen-Beispiele in diesem Artikel von JavaScript betrieben.
Ohne JavaScript müssten wir, um die Schaltfläche „Add Item“ in unserem Beispiel zum Laufen zu bringen, spezielles HTML verwenden, um Daten an den Server zurückzusenden (<form action="...">, falls es Sie interessiert). Dann würde der Browser die gesamte Seite verwerfen und eine aktualisierte Version der gesamten HTML-Datei neu laden. Wenn diese Einkaufsliste Teil einer größeren Seite wäre, würde alles andere, was der Benutzer gerade tat, verloren gehen. Nach unten gescrollt? Sie sind wieder ganz oben. Sehen Sie sich ein Video an? Es beginnt von vorne. So funktionierten alle Webanwendungen lange Zeit: Jedes Mal, wenn ein Benutzer mit einer Webseite interagierte, war es, als ob er seinen Webbrowser schloss und wieder öffnete. Das ist bei diesem einfachen Beispiel kein großes Problem, aber bei einer großen, komplexen Seite, deren Laden eine Weile dauern kann, ist es weder für den Browser noch für den Server effizient.
Wenn wir möchten, dass sich auf einer Webseite etwas ändert, ohne die gesamte Seite neu zu laden, benötigen wir JavaScript (nicht zu verwechseln mit Java, was eine völlig andere Sprache ist... fangen Sie nicht damit an). Versuchen wir, etwas hinzuzufügen
Wenn wir jetzt Text in das Feld eingeben und auf die Schaltfläche „Add Item“ klicken, wird unser neues Element zur Liste hinzugefügt und die Elementanzahl oben aktualisiert! In einer echten App würden wir auch Code hinzufügen, um das neue Element im Hintergrund an den Server zu senden, damit es beim nächsten Laden der Seite immer noch angezeigt wird.
In diesem einfachen Beispiel ist die Trennung von JavaScript von HTML und CSS sinnvoll. Traditionell wurden auch kompliziertere Interaktionen auf diese Weise hinzugefügt: HTML wird geladen und angezeigt, und JavaScript läuft danach, um Dinge hinzuzufügen und zu ändern. Wenn die Dinge jedoch komplexer werden, müssen wir die Dinge in unserem JavaScript besser verfolgen.
Wenn wir diese Einkaufslisten-App weiterentwickeln würden, würden wir wahrscheinlich als Nächstes Schaltflächen zum Bearbeiten oder Entfernen von Elementen aus der Liste hinzufügen. Nehmen wir an, wir schreiben das JavaScript für eine Schaltfläche, die ein Element entfernt, aber wir vergessen, den Code hinzuzufügen, der die Gesamtanzahl der Elemente oben auf der Seite aktualisiert. Plötzlich haben wir einen Fehler: Nachdem ein Benutzer ein Element entfernt hat, stimmt die Gesamtzahl auf der Seite nicht mit der Liste überein! Sobald wir den Fehler bemerken, beheben wir ihn, indem wir dieselbe Zeile totalText.innerHTML aus unserem „Add Item“-Code zum „Remove Item“-Code hinzufügen. Jetzt haben wir denselben Code an mehr als einer Stelle dupliziert. Nehmen wir später an, wir möchten diesen Code so ändern, dass anstelle von „(2 items)“ oben auf der Seite „Items: 2“ steht. Wir müssen sicherstellen, dass wir es an allen drei Stellen aktualisieren: im HTML, im JavaScript für die Schaltfläche „Add Item“ und im JavaScript für die Schaltfläche „Remove Item“. Wenn wir das nicht tun, haben wir einen weiteren Fehler, bei dem sich dieser Text nach einer Benutzerinteraktion abrupt ändert.
In diesem einfachen Beispiel können wir bereits sehen, wie schnell diese Dinge unübersichtlich werden können. Es gibt Möglichkeiten, unser JavaScript zu organisieren, um diese Art von Problem einfacher zu handhaben, aber wenn die Dinge immer komplexer werden, müssen wir die Dinge ständig umstrukturieren und umschreiben, um Schritt zu halten. Solange HTML und JavaScript getrennt gehalten werden, kann viel Aufwand erforderlich sein, um sicherzustellen, dass alles zwischen ihnen synchron gehalten wird. Das ist einer der Gründe, warum neue JavaScript-Frameworks wie React an Bedeutung gewonnen haben: Sie sind darauf ausgelegt, die Beziehungen zwischen Dingen wie HTML und JavaScript aufzuzeigen. Um zu verstehen, wie das funktioniert, müssen wir zunächst nur ein ganz kleines bisschen Informatik verstehen.
Zwei Arten der Programmierung
Das Schlüsselkonzept, das hier verstanden werden muss, ist die Unterscheidung zwischen zwei gängigen Programmierstilen. (Es gibt natürlich noch andere Programmierstile, aber wir beschäftigen uns hier nur mit zweien davon.) Die meisten Programmiersprachen eignen sich für den einen oder den anderen, und einige können auf beide Arten verwendet werden. Es ist wichtig, beide zu verstehen, um den Hauptvorteil von HTML-in-JS aus der Sicht eines JavaScript-Entwicklers zu verstehen.
- Imperative Programmierung: Das Wort „imperativ“ impliziert, dass man einen Computer anweist, etwas zu tun. Eine Zeile imperativen Codes ähnelt einem Imperativsatz im Deutschen: Sie gibt dem Computer eine spezifische Anweisung, die er befolgen soll. Bei der imperativen Programmierung müssen wir dem Computer genau sagen, wie er jede Kleinigkeit tun soll, die wir von ihm verlangen. In der Webentwicklung wird dies langsam als „die alte Art“, Dinge zu tun, betrachtet und ist das, was man mit Vanilla JavaScript oder Bibliotheken wie jQuery macht. Das JavaScript in meinem obigen Einkaufslistenbeispiel ist imperativer Code.
- Imperativ: „Mache X, dann mache Y, dann mache Z“.
- Beispiel: Wenn der Benutzer dieses Element auswählt, füge die Klasse
.selectedhinzu; und wenn der Benutzer die Auswahl aufhebt, entferne die Klasse.selected.
- Deklarative Programmierung: Dies ist eine abstraktere Ebene über der imperativen Programmierung. Anstatt dem Computer Anweisungen zu geben, „deklarieren“ wir stattdessen, was die Ergebnisse sein sollen, nachdem der Computer etwas getan hat. Unsere Tools (z. B. React) finden automatisch das Wie für uns heraus. Diese Tools sind im Inneren mit imperativem Code aufgebaut, dem wir von außen keine Beachtung schenken müssen.
- Deklarativ: „Das Ergebnis soll XYZ sein. Tue, was immer du tun musst, damit das passiert.“
- Beispiel: Dieses Element hat die Klasse
.selected, wenn der Benutzer es ausgewählt hat.
HTML ist eine deklarative Sprache
Vergessen Sie JavaScript für einen Moment. Hier ist eine wichtige Tatsache: HTML an sich ist eine deklarative Sprache. In einer HTML-Datei können Sie etwas wie folgt deklarieren
<section>
<h1>Hello</h1>
<p>My name is Mike.</p>
</section>
Wenn ein Webbrowser dieses HTML liest, findet er diese imperativen Schritte für Sie heraus und führt sie aus
- Erstelle ein section-Element
- Erstelle ein heading-Element der Stufe 1
- Setze den inneren Text des heading-Elements auf „Hello“
- Platziere das heading-Element in das section-Element
- Erstelle ein paragraph-Element
- Setze den inneren Text des paragraph-Elements auf „My name is Mike“
- Platziere das paragraph-Element in das section-Element
- Platziere das section-Element in das Dokument
- Zeige das Dokument auf dem Bildschirm an
Als Webentwickler sind die Details, wie ein Browser diese Dinge tut, irrelevant; alles, was zählt, ist, dass er sie tut. Dies ist ein perfektes Beispiel für den Unterschied zwischen diesen beiden Arten der Programmierung. Kurz gesagt, HTML ist eine deklarative Abstraktion, die um die imperative Anzeigemaschine eines Webbrowsers gewickelt ist. Es kümmert sich um das „Wie“, sodass Sie sich nur um das „Was“ kümmern müssen. Sie können das Leben genießen, indem Sie deklaratives HTML schreiben, weil die netten Leute bei Mozilla oder Google oder Apple den imperativen Code für Sie geschrieben haben, als sie Ihren Webbrowser bauten.
JavaScript ist eine imperative Sprache
Wir haben uns bereits ein einfaches Beispiel für imperatives JavaScript im obigen Einkaufslistenbeispiel angesehen, und ich habe erwähnt, wie die Komplexität der Funktionen einer App Auswirkungen auf den Aufwand für deren Implementierung und das Potenzial für Fehler bei dieser Implementierung hat. Sehen wir uns nun eine etwas komplexere Funktion an und wie sie durch einen deklarativen Ansatz vereinfacht werden kann.
Stellen Sie sich eine Webseite vor, die Folgendes enthält
- Eine Liste beschrifteter Kontrollkästchen, wobei jede Zeile beim Auswählen in eine andere Farbe wechselt
- Text am unteren Rand wie „1 of 4 selected“, der aktualisiert werden soll, wenn sich die Kontrollkästchen ändern
- Eine Schaltfläche „Select All“, die deaktiviert werden soll, wenn bereits alle Kontrollkästchen ausgewählt sind
- Eine Schaltfläche „Select None“, die deaktiviert werden soll, wenn keine Kontrollkästchen ausgewählt sind
Hier ist eine Implementierung davon in einfachem HTML, CSS und imperativem JavaScript
Es gibt hier nicht viel CSS-Code, weil ich das wunderbare PatternFly Design System verwende, das den größten Teil des CSS für mein Beispiel bereitstellt. Ich habe ihre CSS-Datei in den CodePen-Einstellungen importiert.
All die kleinen Dinge
Um diese Funktion mit imperativem JavaScript zu implementieren, müssen wir dem Browser mehrere detaillierte Anweisungen geben. Dies ist das englischsprachige Äquivalent zum Code in meinem obigen Beispiel
- In unserem HTML deklarieren wir die anfängliche Struktur der Seite
- Es gibt vier Zeilenelemente, von denen jedes ein Kontrollkästchen enthält. Das dritte Kästchen ist aktiviert.
- Es gibt einen zusammenfassenden Text, der „1 of 4 selected“ lautet.
- Es gibt eine Schaltfläche „Select All“, die aktiviert ist.
- Es gibt eine Schaltfläche „Select None“, die deaktiviert ist.
- In unserem JavaScript schreiben wir Anweisungen, was sich ändern soll, wenn jedes dieser Ereignisse eintritt
- Wenn sich ein Kontrollkästchen von nicht aktiviert auf aktiviert ändert
- Suchen Sie das Zeilenelement, das das Kontrollkästchen enthält, und fügen Sie die CSS-Klasse
.selectedhinzu. - Suchen Sie alle Kontrollkästchenelemente in der Liste und zählen Sie, wie viele aktiviert und wie viele nicht aktiviert sind.
- Suchen Sie das zusammenfassende Textelement und aktualisieren Sie es mit der aktivierten Zahl und der Gesamtzahl.
- Suchen Sie das Schaltflächenelement „Select None“ und aktivieren Sie es, wenn es deaktiviert war.
- Wenn jetzt alle Kontrollkästchen aktiviert sind, suchen Sie das Schaltflächenelement „Select All“ und deaktivieren Sie es.
- Suchen Sie das Zeilenelement, das das Kontrollkästchen enthält, und fügen Sie die CSS-Klasse
- Wenn sich ein Kontrollkästchen von aktiviert auf nicht aktiviert ändert
- Suchen Sie das Zeilenelement, das das Kontrollkästchen enthält, und entfernen Sie die Klasse
.selected. - Suchen Sie alle Kontrollkästchenelemente in der Liste und zählen Sie, wie viele aktiviert und nicht aktiviert sind.
- Suchen Sie das zusammenfassende Textelement und aktualisieren Sie es mit der aktivierten Zahl und der Gesamtzahl.
- Suchen Sie das Schaltflächenelement „Select All“ und aktivieren Sie es, wenn es deaktiviert war.
- Wenn jetzt alle Kontrollkästchen nicht aktiviert sind, suchen Sie das Schaltflächenelement „Select None“ und deaktivieren Sie es.
- Suchen Sie das Zeilenelement, das das Kontrollkästchen enthält, und entfernen Sie die Klasse
- Wenn auf die Schaltfläche „Select All“ geklickt wird
- Suchen Sie alle Kontrollkästchenelemente in der Liste und aktivieren Sie sie alle.
- Suchen Sie alle Zeilenelemente in der Liste und fügen Sie die Klasse
.selectedhinzu. - Suchen Sie das zusammenfassende Textelement und aktualisieren Sie es.
- Suchen Sie die Schaltfläche „Select All“ und deaktivieren Sie sie.
- Suchen Sie die Schaltfläche „Select None“ und aktivieren Sie sie.
- Wenn auf die Schaltfläche „Select None“ geklickt wird
- Suchen Sie alle Kontrollkästchenelemente in der Liste und deaktivieren Sie sie alle.
- Suchen Sie alle Zeilenelemente in der Liste und entfernen Sie die Klasse
.selected. - Suchen Sie das zusammenfassende Textelement und aktualisieren Sie es.
- Suchen Sie die Schaltfläche „Select All“ und aktivieren Sie sie.
- Suchen Sie die Schaltfläche „Select None“ und deaktivieren Sie sie.
- Wenn sich ein Kontrollkästchen von nicht aktiviert auf aktiviert ändert
Wow. Das ist viel, oder? Nun, wir sollten daran denken, für jede einzelne dieser Anweisungen Code zu schreiben. Wenn wir eine dieser Anweisungen vergessen oder vermasseln, bekommen wir einen Fehler, bei dem die Gesamtzahlen nicht mit den Kontrollkästchen übereinstimmen, oder eine Schaltfläche aktiviert ist, die beim Anklicken nichts tut, oder eine Zeile die falsche Farbe hat, oder etwas anderes, woran wir nicht gedacht haben und erst herausfinden, wenn sich ein Benutzer beschwert.
Das große Problem hierbei ist, dass es keine einzige Quelle der Wahrheit für den Zustand unserer App gibt, der in diesem Fall lautet: „Welche Kontrollkästchen sind aktiviert?“ Die Kontrollkästchen wissen natürlich, ob sie aktiviert sind oder nicht, aber die Zeilenstile müssen es auch wissen, der zusammenfassende Text muss es wissen, und jede Schaltfläche muss es wissen. Fünf Kopien dieser Informationen werden separat im gesamten HTML gespeichert, und wenn sich die Informationen an einer dieser Stellen ändern, muss der JavaScript-Entwickler dies erkennen und imperativen Code schreiben, um die anderen synchron zu halten.
Dies ist immer noch nur ein einfaches Beispiel für eine kleine Komponente einer Seite. Wenn sich das wie Kopfschmerzen anhört, stellen Sie sich vor, wie komplex und fragil eine Anwendung wird, wenn Sie das Ganze auf diese Weise schreiben müssen. Für viele komplexe moderne Webanwendungen ist dies keine skalierbare Lösung.
Hin zu einer einzigen Quelle der Wahrheit
Tools wie React ermöglichen es uns, JavaScript auf deklarative Weise zu verwenden. So wie HTML eine deklarative Abstraktion ist, die um die Anzeigebefehle des Webbrowsers gewickelt ist, ist React eine deklarative Abstraktion, die um JavaScript gewickelt ist.
Erinnern Sie sich, wie HTML es uns ermöglichte, uns auf die Struktur einer Seite zu konzentrieren und nicht auf die Details, wie der Browser diese Struktur anzeigt? Nun, wenn wir React verwenden, können wir uns wieder auf die Struktur konzentrieren, indem wir sie basierend auf Daten definieren, die an einem einzigen Ort gespeichert sind. Wenn sich diese Quelle der Wahrheit ändert, aktualisiert React die Struktur der Seite automatisch für uns. Es kümmert sich um die imperativen Schritte hinter den Kulissen, genau wie der Webbrowser es für HTML tut. (Obwohl React hier als Beispiel verwendet wird, ist dieses Konzept nicht einzigartig für React und wird auch von anderen Frameworks wie Vue verwendet.)
Kehren wir zu unserer Liste von Kontrollkästchen aus dem obigen Beispiel zurück. In diesem Fall ist die Wahrheit, die uns interessiert, einfach: Welche Kontrollkästchen sind aktiviert? Die anderen Details auf der Seite (z. B. was die Zusammenfassung besagt, die Farbe der Zeilen, ob die Schaltflächen aktiviert sind oder nicht) sind Effekte, die von derselben Wahrheit abgeleitet werden. Warum sollten sie also ihre eigene Kopie dieser Informationen benötigen? Sie sollten einfach die einzige Quelle der Wahrheit als Referenz verwenden, und alles auf der Seite sollte „einfach wissen“, welche Kontrollkästchen aktiviert sind, und sich entsprechend verhalten. Man könnte sagen, dass die Zeilenelemente, der zusammenfassende Text und die Schaltflächen alle in der Lage sein sollten, automatisch auf ein aktiviertes oder deaktiviertes Kontrollkästchen zu reagieren. (Sehen Sie, was ich da gemacht habe?)
Sag mir, was du willst (was du wirklich, wirklich willst)
Um diese Seite mit React zu implementieren, können wir die Liste durch ein paar einfache Deklarationen von Fakten ersetzen
- Es gibt eine Liste von Wahr/Falsch-Werten namens
checkboxValues, die darstellt, welche Kästchen aktiviert sind.- Beispiel:
checkboxValues = [false, false, true, false] - Diese Liste repräsentiert die Wahrheit, dass wir vier Kontrollkästchen haben und dass das dritte aktiviert ist.
- Beispiel:
- Für jeden Wert in
checkboxValuesgibt es ein Zeilenelement, das- eine CSS-Klasse namens
.selectedhat, wenn der Wert wahr ist, und - ein Kontrollkästchen enthält, das aktiviert ist, wenn der Wert wahr ist.
- eine CSS-Klasse namens
- Es gibt ein zusammenfassendes Textelement, das den Text „
{x}von{y}ausgewählt“ enthält, wobei{x}die Anzahl der wahren Werte incheckboxValuesund{y}die Gesamtzahl der Werte incheckboxValuesist. - Es gibt eine Schaltfläche „Select All“, die aktiviert ist, wenn es falsche Werte in
checkboxValuesgibt. - Es gibt eine Schaltfläche „Select None“, die aktiviert ist, wenn es wahre Werte in
checkboxValuesgibt. - Wenn auf ein Kontrollkästchen geklickt wird, ändert sich sein entsprechender Wert in
checkboxValues. - Wenn auf die Schaltfläche „Select All“ geklickt wird, werden alle Werte in
checkboxValuesauf true gesetzt. - Wenn auf die Schaltfläche „Select None“ geklickt wird, werden alle Werte in
checkboxValuesauf false gesetzt.
Sie werden feststellen, dass die letzten drei Punkte immer noch imperative Anweisungen sind („Wenn dies passiert, tue das“), aber das ist der einzige imperative Code, den wir schreiben müssen. Es sind drei Zeilen Code, und sie alle aktualisieren die einzige Quelle der Wahrheit. Der Rest dieser Punkte sind Deklarationen („es gibt ein…“), die jetzt direkt in die Definition der Seitenstruktur integriert sind. Um dies zu tun, schreiben wir unsere Elemente in einer speziellen JavaScript-Syntax, die von React namens JSX bereitgestellt wird und HTML ähnelt, aber JavaScript-Logik enthalten kann. Das gibt uns die Möglichkeit, Logik wie „if“ und „for each“ mit der HTML-Struktur zu mischen, sodass die Struktur je nach Inhalt von checkboxValues zu einem bestimmten Zeitpunkt unterschiedlich sein kann.
Hier ist dasselbe Einkaufslistenbeispiel wie oben, diesmal mit React implementiert
JSX ist definitiv seltsam. Als ich es zum ersten Mal sah, fühlte es sich einfach falsch an. Meine erste Reaktion war: „Was zum Teufel ist das? HTML gehört nicht in JavaScript!“ Ich war nicht allein. Dennoch ist es kein HTML, sondern JavaScript, das wie HTML aussieht. Es ist auch ziemlich mächtig.
Erinnern Sie sich an die Liste der 20 imperativen Anweisungen oben? Jetzt haben wir drei. Zum Preis der Definition unseres HTML innerhalb unseres JavaScript bekommen wir den Rest kostenlos. React macht sie einfach für uns, wann immer sich checkboxValues ändert.
Mit diesem Code ist es nun unmöglich, dass die Zusammenfassung nicht mit den Kontrollkästchen übereinstimmt, oder dass die Farbe einer Zeile falsch ist, oder dass eine Schaltfläche aktiviert ist, wenn sie deaktiviert sein sollte. Es gibt eine ganze Kategorie von Fehlern, die wir in unserer App jetzt unmöglich haben können: Quellen der Wahrheit, die nicht synchron sind. Alles fließt von der einzigen Quelle der Wahrheit ab, und wir Entwickler können weniger Code schreiben und nachts besser schlafen. Nun, JavaScript-Entwickler können das zumindest…
Es ist ein Kompromiss
Wenn Webanwendungen komplexer werden, hat die Aufrechterhaltung der klassischen Trennung der Belange zwischen HTML und JavaScript immer schmerzhaftere Kosten. HTML wurde ursprünglich für statische Dokumente entwickelt, und um diesen Dokumenten komplexere interaktive Funktionen hinzuzufügen, muss imperatives JavaScript mehr Dinge im Auge behalten und wird verwirrender und fragiler.
Der Vorteil: Vorhersagbarkeit, Wiederverwendbarkeit und Komposition
Die Möglichkeit, eine einzige Quelle der Wahrheit zu verwenden, ist der wichtigste Vorteil dieses Musters, aber der Kompromiss bietet uns auch andere Vorteile. Das Definieren von Elementen unserer Seite als JavaScript-Code bedeutet, dass wir Teile davon in wiederverwendbare Komponenten umwandeln können, wodurch wir vermeiden, dass wir dasselbe HTML an mehreren Stellen kopieren und einfügen. Wenn wir eine Komponente ändern müssen, können wir diese Änderung an einer Stelle vornehmen, und sie wird überall in unserer Anwendung aktualisiert (oder in vielen Anwendungen, wenn wir wiederverwendbare Komponenten für andere Teams veröffentlichen).
Wir können diese einfachen Komponenten nehmen und sie wie LEGO-Steine zusammensetzen, um komplexere und nützlichere Komponenten zu erstellen, ohne dass sie zu verwirrend werden, um damit zu arbeiten. Und wenn wir Komponenten verwenden, die von anderen erstellt wurden, können wir sie einfach aktualisieren, wenn sie Verbesserungen veröffentlichen oder Fehler beheben, ohne unseren Code umschreiben zu müssen.
Der Nachteil: Es ist überall JavaScript
All diese Vorteile haben ihren Preis. Es gibt gute Gründe, warum Menschen Wert auf die Trennung von HTML und JavaScript legen, und um diese anderen Vorteile zu erzielen, müssen wir sie zu einem kombinieren. Wie ich bereits erwähnt habe, verkompliziert die Abkehr von einfachen HTML-Dateien den Arbeitsablauf von jemandem, der sich vorher nicht um JavaScript kümmern musste. Es kann bedeuten, dass jemand, der zuvor selbst Änderungen an einer Anwendung vornehmen konnte, nun zusätzliche komplexe Fähigkeiten erlernen muss, um diese Autonomie aufrechtzuerhalten.
Es kann auch technische Nachteile geben. Zum Beispiel erwarten einige Tools wie Linter und Parser reguläres HTML, und einige imperative JavaScript-Plugins von Drittanbietern können schwieriger zu handhaben sein. Außerdem ist JavaScript nicht die am besten entwickelte Sprache; es ist nur das, was wir zufällig in unseren Webbrowsern haben. Neuere Tools und Funktionen verbessern es, aber es hat immer noch einige Fallstricke, die Sie kennen müssen, bevor Sie produktiv damit arbeiten können.
Ein weiteres potenzielles Problem ist, dass, wenn die semantische Struktur einer Seite in abstrakte Komponenten zerlegt wird, es für Entwickler leicht werden kann, nicht mehr darüber nachzudenken, welche tatsächlichen HTML-Elemente am Ende generiert werden. Spezifische HTML-Tags wie <section> und <aside> haben spezifische semantische Bedeutungen, die verloren gehen, wenn generische Tags wie <div> und <span> verwendet werden, selbst wenn sie auf einer Seite visuell gleich aussehen. Dies ist besonders wichtig für die Barrierefreiheit. Beispielsweise wirken sich diese Entscheidungen darauf aus, wie sich Screenreader-Software für sehbehinderte Benutzer verhält. Es mag nicht der aufregendste Teil sein, aber JavaScript-Entwickler sollten immer daran denken, dass semantisches HTML der wichtigste Teil einer Webseite ist.
Verwenden Sie es, wenn es Ihnen hilft, nicht, weil es „gerade angesagt ist“
Es ist zum Trend geworden, dass Entwickler bei jedem Projekt zu Frameworks greifen. Manche sind der Meinung, dass die Trennung von HTML und JavaScript überholt ist, aber das stimmt nicht. Für eine einfache statische Website, die nicht viel Benutzerinteraktion erfordert, lohnt sich der Aufwand nicht. Die enthusiastischeren React-Fans mögen mir hier widersprechen, aber wenn Ihr JavaScript nur dazu dient, eine nicht-interaktive Webseite zu erstellen, sollten Sie JavaScript nicht verwenden. JavaScript lädt nicht so schnell wie reguläres HTML. Wenn Sie also keine signifikante Verbesserung der Entwicklererfahrung oder Codezuverlässigkeit erzielen, richtet es mehr Schaden als Nutzen an.
Sie müssen auch nicht Ihre gesamte Website in React erstellen! Oder Vue! Oder Was auch immer! Viele Leute wissen das nicht, weil alle Tutorials da draußen zeigen, wie man React für das Ganze verwendet. Wenn Sie nur ein kleines, komplexes Widget auf einer ansonsten einfachen Website haben, können Sie React für diese eine Komponente verwenden. Sie müssen sich nicht immer um webpack oder Redux oder Gatsby oder all den anderen Mist kümmern, den Ihnen Leute als „Best Practices“ für Ihre React-App verkaufen wollen.
Für eine ausreichend komplexe Anwendung ist deklarative Programmierung den Aufwand absolut wert. Es ist ein Wendepunkt, der Entwickler auf der ganzen Welt in die Lage versetzt hat, erstaunliche, robuste und zuverlässige Software mit Zuversicht zu erstellen, ohne sich um die kleinen Dinge kümmern zu müssen. Ist React im Besonderen die bestmögliche Lösung für diese Probleme? Nein. Wird es einfach durch das nächste Ding ersetzt werden? Irgendwann. Aber deklarative Programmierung wird nicht verschwinden, und das nächste Ding wird es wahrscheinlich einfach besser machen.
Was habe ich über CSS-in-JS gehört?
Das fasse ich nicht an.
Ich bin Full-Stack-Entwickler, aber es gibt Leute, die als Front-End-Designer bekannt sind, die keine Kenntnisse in JavaScript haben, und das Mischen von JavaScript mit HTML frustriert sie.
Obwohl Frameworks wie Vue und React viele Dinge automatisch aktualisieren, gibt es einen Fehler, wenn der Entwickler vergessen hat, etwas zu programmieren; Frameworks beheben nicht alles automatisch. Frameworks sind also nützlich für die schnelle Entwicklung, aber zu sagen – wir können diese Änderung an einer Stelle vornehmen und sie wird überall in unserer Anwendung aktualisiert (wenn Front-End-Frameworks verwendet werden) – könnte übertrieben sein.
Außerdem ist es besser, HTML und JavaScript auf öffentlich zugänglichen Seiten (ohne Login) zu trennen; und ein Front-End-Framework auf dynamischen Seiten zu verwenden, die von Live-Aktualisierungen durch Benutzerinteraktion abhängen.
Entwickler müssen solche Frameworks mit Bedacht auswählen und verwenden. Ich stimme Ihrer Botschaft in dem Abschnitt – Verwenden Sie es, wenn es Ihnen hilft, nicht, weil es „gerade angesagt ist“ – voll und ganz zu.
Absolut! Entwickler müssen immer noch aufpassen, und man kann definitiv immer noch viele Arten von Fehlern haben. Ich meine nur, dass Tools wie dieses es ermöglichen, einzelne Quellen der Wahrheit zu definieren und zu verwenden. Der Entwickler muss dies immer noch nutzen und sich daran halten.
Was für ein gut geschriebener Artikel.
Fesselnde Lektüre.
Ich möchte hinzufügen, dass ich als Front-End-Entwickler, der sich auf imperative Programmierung verlässt, den Zweck oder den Punkt, den Mike mit diesem Artikel machen wollte, vollständig verstanden habe.
Es geht darum, sich bewusst zu sein, was diese neuen Frameworks sind, warum die Leute angefangen haben, sie zu verwenden, und welche Vorteile sie haben, und natürlich, welche Dinge an ihnen nicht so sympathisch sind.
Mike informiert uns darüber, wann und wo etwas wie React nützlich wäre und wo es unnötig oder völliger Overkill wäre.
Ich frage mich dann, ob ich wertvolle Zeit verschwende, wenn ich mir nicht eine Ewigkeit damit verbringe, mit nativem js, jquery zu spielen und neue Dinge mit diesen Sprachen auszuprobieren und Dinge zu lernen, die ich mit diesen beiden tun könnte, von denen ich dachte, ich könnte sie nie tun, und ob ich stattdessen in den Pool mit den js-Framework-Leuten „eintauchen“ sollte.
Die Sache ist die, dass ich noch keinen Grund hatte, eines davon zu verwenden. Bis dahin bleibe ich bei html5+css3+javascript & jquery+php und mysql
Ich bin mir sicher, dass ich, wenn die Zeit reif ist, mit dem Sprung zum nächsten großen Framework einverstanden sein werde, heh.
Schade, dass es deine Zeit verschwendet hat. Gut, dass es dir genug Zeit gelassen hat, einen ausführlichen Kommentar zu schreiben!
Toller Artikel, danke Mike.
“What’s this I’ve heard about CSS-in-JS?
I’m not touching that one.”
Freut mich, dass es dir gefällt! Heh, ja, das ist ein Thema für einen anderen Tag :) Ich habe es selbst noch nicht ganz verstanden.
Ich bin Tech-Lead bei einem niederländischen Startup und Engineering Lead bei einer pakistanischen Tech-Firma.
Ich werde hier einen stichhaltigen Punkt machen, aber davor muss ich etwas rechtfertigen, meinen Standpunkt und meine Position. Meine Fähigkeiten umfassen Cloud & Solution Architect, Computer Systems Engineer, Computer Architect, Project & Product Manager, IoT Expert, Full-Stack Developer, Robotist und Graphics Designer.
Zunächst dachte ich, dieser Artikel sei ein Vergleich zwischen Server-Side-Rendering oder eine Rezension von ejs oder nest und statischen HTML-Vorlagen, das war er nicht.
Dann dachte ich, es ginge um HTML5, seine APIs und die Leistung, die es Webentwicklern gegeben hat, und die verfügbaren JS-Wrapper, um sie zu konsumieren, das war es nicht.
Haben Sie Geduld mit mir, da dieser Artikel Zeitverschwendung war, aber nicht ganz nutzlos, aber nicht das, was der Titel vermuten lässt.
Stattdessen war es ein Vergleich zwischen JSX und HTML. Der Artikel bezeichnet HTML als deklarative Sprache. SQL ist eine deklarative Sprache, mein Freund. HTML ist nur Markup, es ist eine Auszeichnungssprache. Abgesehen von HTML5. Und wenn Sie über Inline-Funktionen sprechen, müssen Sie sich darüber informieren, wie Browser funktionieren und wie sie Webseiten rendern.
Und JSX ist kein HTML, es ist nur eine schicke neue Funktion, die auch in React verfügbar ist und die Sie möglicherweise nutzen können, indem Sie Babel importieren, ts config einrichten und Ihren Linter optimieren.
Vielleicht möchten Sie keine Artikel mit extrem eingängigen Titeln veröffentlichen, nur um mehr Aufrufe zu erzielen. PS, diese Seite ist CSS tricks. Eine Gruppe von Frontend-Webentwicklern nehme ich an?
Sie müssen HTML nicht in JS aufnehmen, um die App-Entwicklung zu vereinfachen. Frameworks wie Vue und Svelte benötigen keine solche Abstraktion und sind für viele Neulinge einfacher zu verstehen, da sie näher an einfachem HTML/CSS/JS sind
Es stimmt, dies ist nicht die einzige Lösung für diese Probleme, noch ist es die beste. Ich wollte nur erklären, warum man es überhaupt tun könnte. Nach dem, was ich von Vue und Svelte gesehen habe, sind sie auch elegant und möglicherweise zugänglicher (je nachdem, wie man sie verwendet), aber sie haben auch ihre eigenen Nachteile. Vue’s benutzerdefinierte Attribute und Template-Strings machen es auch nicht zu echtem HTML, sondern nur zu einer anderen Abstraktion. Und Svelte ist so eine Black Box, dass ich beim Debuggen wahrscheinlich Schwierigkeiten hätte, es zu durchschauen.
Ich muss mehr über sie lernen, bevor ich sie zu sehr kritisiere. Ich nähere mich diesem Thema definitiv mit hauptsächlich React-Erfahrung und vergleiche es mit meiner Erfahrung mit Dingen wie jQuery. Vielleicht entscheide ich mich stattdessen für Vue oder Svelte :) Danke für die Perspektive!
Wenn Sie Web Components auf eine bestimmte und konsistente Weise verwenden und eine gut dokumentierte Bibliothek für Ihre Benutzer pflegen, können Sie HTML so verwenden, wie es erfunden wurde: um Inhalt und seine Struktur zu DEFINIEREN.
Ich denke, Web Components werden irgendwann die Front-End-Entwicklung beherrschen.
Ich denke, Sie könnten mit Web Components Recht haben, ich habe sie im Auge. Im Moment scheinen sie jedoch nicht reif genug für meine Bedürfnisse zu sein. Wir werden dorthin gelangen!
Beim Lesen des Artikels kam mir genau das in den Sinn. Die vom Autor aufgeführten Probleme sind für React/JSX real, aber Vue.js behält immer noch eine gewisse Trennung der Belange bei. In meinem Unternehmen programmieren Designer normalerweise HTML/CSS, und als wir ein Framework zur Modernisierung unseres Stacks einführten, entschieden wir uns für Vue.js, da die Lernkurve für Designer etwas flacher wäre.
Was ist mit diesen Problemen
Backend: Für Webanwendungen benötigen Sie immer noch eine ganz separate Ebene, z. B. Speichern in einer Datenbank, Speichern und Abrufen von Konfigurationen usw. Durch den Wechsel zu React haben wir nichts davon vereinfacht.
Workflow: Einfaches HTML/CSS/JS erfordert nicht viel Einrichtung für meinen lokalen Laptop oder meinen Standard-Webserver. Sogar ein LAMP-Stack ist ziemlich standardisiert. Ich kann alle Tools verwenden, die ich möchte (Texteditoren usw.). Aber um mit React loszulegen, muss ich mich (zumindest) mit Node, Abhängigkeitsmanagement, rapiden Versionsänderungen herumschlagen…
Teamwork: Einer der Vorteile von Komponenten im React-Stil ist, dass Teams zusammenarbeiten können, ohne die Dinge durcheinander zu bringen. Aber es erfordert auch eine Menge erzwungener Vereinbarungen – diesen Texteditor, diese Version, diesen Anbieter, dieses Plugin. So funktionierten die Dinge in der Pre-HTML-Welt, in der Macs und Windows kaum Dateien austauschen konnten. Deshalb ist „Onboarding“ jetzt so ein Schlagwort: Es bedeutet nicht nur „lernen, wie die Codebasis funktioniert“, sondern „richten Sie Ihre Umgebung genau auf diese Weise ein“.
Ich stimme Ihnen zu, dass React für Sie nützlich sein könnte, wenn Sie eine „App“ erstellen – aber gute altmodische Webseiten fühlen sich in diesem Zeitalter des Drängens auf „Apps“ wie ein nachträglicher Gedanke an.
Es scheint mir, dass Unternehmen wie Google und Facebook davon profitieren, wenn eine Infrastruktur und ein bestimmter Arbeitsstil von ihnen definiert werden. Das ist klassisches Lock-in.
Danke für den nachdenklichen Aufsatz.
Freut mich, dass Ihnen der Artikel gefallen hat! Ich denke, ich stimme vielem von dem zu, was Sie hier gesagt haben, aber ein paar Dinge
Backend: Stimmt, der Wechsel zu React löst keine Backend-Probleme, der Vergleich, den ich anstellen möchte, ist Frontend-spezifisch. Aber meiner Meinung nach, wenn Sie kein HTML auf dem Server rendern, entkoppelt das die Präsentation des Dokuments schön von der API / Geschäftslogik, sodass das Backend nur noch für die Bereitstellung dieser Dinge über eine schöne REST-API oder GraphQL usw. verantwortlich ist. Und Sie können immer noch Tools verwenden, um Ihr React serverseitig für Leistung und SEO zu rendern, wenn Sie möchten, obwohl ich zugeben muss, dass das etwas mühsam sein kann.
Workflow: Für die meisten Projekte mit „React und Freunden“ werden Sie völlig Recht haben. Aber ein Bundler ist nicht zwingend erforderlich: Sie können React (und sogar JSX) in einfachem statischen HTML+JS verwenden, indem Sie
<script>-Tags verwenden, genau wie jQuery. Sie erhalten nicht die Vorteile von Bundlern, aber Sie können auf diese Weise schnelle und einfache Prototypen erstellen oder ein kleines React-Widget zu einer ansonsten statischen Seite hinzufügen, ohne dass webpack erforderlich ist: https://reactjs.org/docs/add-react-to-a-website.htmlTeamwork: Das ist definitiv ein berechtigtes Problem bei all dem, aber ich glaube nicht, dass das ein Problem ist, das einzigartig für etwas wie React ist. Eine organisierte Codebasis war schon immer schwer über Mitarbeiter hinweg zu pflegen.
Alles berechtigte Punkte, aber es ist nie so schwarz-weiß.
„But to get going with React, I need to deal with (at the least) Node, dependency-management, rapid version changes…“
Ja, und das ist für mich die größte Barriere, um einige dieser Tools zu erlernen. Ich habe sowohl IIS- als auch Apache-Server auf meiner Workstation, ich habe Datenbanken, Python, PHP usw., und all das war einfacher zu verstehen, wie man es installiert und konfiguriert, als das, was ich über Node, Paketmanager und all den anderen Overhead gelesen habe, der mit diesen neuen Frameworks einherzugehen scheint. (Wenn jemand ein gutes Tutorial empfehlen kann, wie man das alles auf einer Windows-Workstation einrichtet, wäre das großartig.)
Aber die noch größere Frage, die ich mir beim Lesen von Artikeln über React oder all die anderen auftauchenden Frameworks gestellt habe, war: „Warum?“ Bis ich diesen Artikel las, klang es nach viel zusätzlicher Komplexität ohne allzu großen Nutzen. Oder vielleicht verwendeten die Autoren React in einer Situation, in der es völlig übertrieben war, wie einige der anderen Poster angedeutet haben. Jetzt verstehe ich es, oder zumindest verstehe ich es viel besser als zuvor. Danke, Mike.
Nur eine weitere „Ich kenne React, also bin ich heiliger als du“-Einstellung. Sogar Google hat im Jahr 2020 Probleme mit dem JS-Rendering, also behindern Sie sich selbst, indem Sie JS auf einer E-Commerce-Website verwenden. Wer kann hier das Meme „kleines Gehirn vs. großes Gehirn“ für mich posten?
Wo impliziere ich in meinem Artikel, dass ich heiliger bin als du? Ich entschuldige mich, wenn ich so rübergekommen bin. Ich versuche nur, die Gründe zu erklären, warum man es verwenden könnte. Es hat absolut Schwachstellen. SEO ist ein großes Problem, wenn Sie auf dieses Problem stoßen, denke ich, dass dies unter „verwenden Sie es, wenn es Ihnen hilft“ fällt.
Es ist … null Prozent davon. Buchstäblich kein einziger selbstgefälliger oder unüberlegter Punkt im gesamten Artikel.
Das ist nicht wirklich neu … Blade = HTML-in-PHP, ERB = HTML-in-Ruby, Jinja = HTML-in-Python, JSX = HTML-in-JavaScript.
Früher schrieben Designer Vorlagen und Entwickler schrieben PHP/Python/Ruby. Jetzt ist die sinnvolle Aufteilung zwischen präsentationalen vs. zustandsbehafteten Komponenten.
Ja, ich hätte vielleicht mehr Hintergrundinformationen zur Geschichte anderer serverseitig gerenderter Templating-Frameworks geben sollen. Das ist nur in dem Sinne neu, dass man clientseitige Dinge deklarativ schreiben kann; diese Beispiele fallen meiner Meinung nach immer noch unter den Fehler „Änderungen erfordern das Neuladen der Seite“. Sie sind jedoch absolut bessere Lösungen, wenn Sie nicht viele ausgefallene clientseitige Widgets benötigen. Man kann immer ein bisschen von beidem verwenden :)
Vielleicht hätte es sich gelohnt, auf präsentationale vs. zustandsbehaftete Komponenten einzugehen, aber ich hatte das Gefühl, dass dies den Rahmen des Artikels sprengen würde. Ich weiß es zu schätzen, dass Sie diesen Kontext hinzufügen.
Guter Artikel. Schöne Erklärung.
Bitte lassen Sie mich wissen, wie es sich von Angular unterscheidet.
Wann immer Steuerelemente dynamisch erstellt werden müssen, können wir eines der JQuery oder Angular oder React usw. Frameworks verwenden.
Mir hat die Art und Weise, wie Sie erklärt haben, „Sie können React für diese eine Komponente verwenden“, sehr gut gefallen.
Wenn ich viele HTML-Dateien habe, in denen die Benutzerinteraktion sehr begrenzt ist, und ich nur eine Komponente habe, in der die Interaktion maximal ist, geben Sie bitte ein Beispiel für die Entwicklung der einzelnen Komponente und wie man alle in eine einzige Website integriert und veröffentlicht.
Mein Eindruck vom Hauptunterschied zwischen React und Angular ist, dass React einen Top-Down-Uni-direktionalen Datenfluss bietet (alles kommt von der Quelle der Wahrheit), und Angular eine bidirektionale Datenbindung bietet (verknüpft einige Dinge miteinander, sodass, wenn sich eines davon ändert, sich die anderen automatisch ändern). Ich finde React vorhersehbarer, und obwohl seine Elemente in JSX/JavaScript definiert sind, beschreiben sie normales HTML genauer als Angular, das eine Reihe von benutzerdefinierten Attributen in seinem HTML enthält. React ist auch weniger voreingenommen (was gut und schlecht sein kann), während Angular so etwas wie ein All-in-One-Paket ist, bei dem man alles auf „die Angular-Weise“ machen muss. Jedes hat seinen Platz, und ich muss zugeben, dass ich voreingenommen bin, da ich viel mehr Erfahrung mit React habe.
Ein Beispiel für das Hinzufügen einer einzelnen React-Komponente zu einer ansonsten Nicht-React-Website finden Sie auf der Seite in der React-Dokumentation, die ich im Abschnitt „Verwenden Sie es, wenn es Ihnen hilft“ verlinkt habe: https://reactjs.org/docs/add-react-to-a-website.html. Im Grunde können Sie ein leeres
<div>irgendwo auf Ihrer Website einfügen und dann React anweisen, dort zu rendern, und es übernimmt die Kinder dieses divs und lässt den Rest Ihrer Seite in Ruhe.Ich habe nichts gegen den HTML/CSS-in-JS-Ansatz, solange Ihre Ausgabe gut gestaltet ist. Diese Gestaltung zu liefern, ist nur möglich, wenn man eine großartige Grundlage in den Grundlagen der drei genannten Sprachen hat.
Damit meine ich, dass die Komponenten keine „div soup“ in den DOM rendern und gut (semantisch) mit den Komponenten funktionieren, in die sie eingefügt werden.
Bei CSS-in-JS, solange es sich nicht um Inline-Styles handelt und die Entwicklererfahrung mit CSS-in-JS gut ist, bin ich dafür.
100% einverstanden.
Tim Berners-Lee hatte die Weisheit, dies vorauszusehen. Seine Regel der geringsten Mächtigkeit war jahrelang ein Leitprinzip des W3C.
https://www.w3.org/2001/tag/doc/leastPower
Und in Bezug auf HTML
Weise Worte, dem kann ich nicht widersprechen. Das ist eine wichtige Überlegung beim Kompromiss. Ich denke, React wird am besten verwendet, wenn es Dinge wie die Möglichkeit zur Indizierung und zum Lesen von Daten beibehält, entweder durch serverseitiges Rendering (z. B. Gatsby) oder indem das Backend der Anwendung so konzipiert wird, dass es eine öffentliche API enthält, sodass die React-Ansicht nur ein Frontend ist, das dieselben Daten konsumiert, die auch programmatisch für andere Verwendungszwecke verfügbar sind.
Was ist der Unterschied zwischen Framework und Bibliothek?
Um ehrlich zu sein, denke ich, dass die Unterscheidung in der JavaScript-Welt etwas verloren gegangen ist; sie werden oft synonym verwendet, und ich mache mich dessen schuldig.
Laut Wikipedia „bietet eine Bibliothek Funktionen, die vom übergeordneten Code aufgerufen werden können, während ein Framework das gesamte Anwendungsdesign definiert.“ (https://en.wikipedia.org/wiki/JavaScript_framework) Nach dieser Definition würde ich React als Bibliothek und nicht als Framework betrachten. Und tatsächlich nennt es Reacts eigene Website so. Danke für den Hinweis!
Ich mag Frameworks wie React, aber ich hasse es auch, wie sie (meistens) einen Benutzer ohne JavaScript im Dunkeln lassen. Ich persönlich kombiniere React gerne mit einem Server-Side-Render für das anfängliche Laden.
Ich habe das Gefühl, dass dieser Beitrag auf dem falschen Fuß gestartet ist, indem er erwähnt, dass man Javascript braucht, um zu verhindern, dass die ganze Seite neu geladen wird. Die meisten Websites zur Codebearbeitung posten in einen iFrame, um die Ergebnisse zu aktualisieren. Es ist wichtig, dass wir nicht all die HTML- und CSS-Tools vergessen, die uns zur Verfügung stehen.
Ich werde in Kürze eine Reise antreten, um einen Echtzeit-IRC-Client zu erstellen, der nahtlos ohne JS und/oder Cookies funktioniert (hauptsächlich unter Verwendung einiger CSS-Tricks!).
Können Sie das näher erläutern? Ich würde denken, dass der Inhalt dieses Frames immer noch dieselben Einschränkungen hat, aber ich bin noch nie auf solchen Code gestoßen. Das klingt nach einer interessanten Lösung!
Beobachten Sie dann einfach, was WebAssembly in einigen Jahren tun wird. Viele Unternehmenssysteme werden zu dummen Terminals mit nichts weiter als einem Canvas und einem Websocket werden und einem VNC-Client ähneln.
Es gibt so viel zu entpacken, und wir sind sicherlich sehr weit von unseren Wurzeln abgekommen. Wie löst das Greifen zu einem Tool wie React das Problem einer einzigen Quelle der Wahrheit anders als die Verwendung von ES-Modulen, Klassen und commonJS? Und wie sieht es mit dem Vorlagen-Tag und HTML-Importen aus, um Markup und Komponenten zu trennen?
Die Eingaben fehlen in den Beispielen alle Beschriftungen, und die Tabellenzusammenfassung sollte ein caption-Element mit aria-live=assertive sein.
Vielen Dank für den Hinweis auf die fehlenden Beschriftungen und Aria-Attribute! Ich muss zurückgehen und diese aktualisieren und das praktizieren, was ich predige. Ich lerne immer noch, wie man barrierefreies Markup erstellt, ich bin einer der JavaScript-Entwickler, die all dies in der falschen Reihenfolge gelernt haben!
Was Ihre Frage betrifft, diese Dinge lösen ein anderes Problem der Quelle der Wahrheit und helfen, wiederholten Code zu vermeiden. React verwaltet die Quelle der Wahrheit speziell für den Ansichtszustand und hilft, wiederholten Zustand (Benutzereingabe, von einer API geladene Daten, Ergebnisse der Benutzerinteraktion usw.) sowie Code zu vermeiden.
Dies ist ein hilfreicher Artikel. Besonders für relative Neulinge. Ich denke, Mike ist sich der Absicht des Artikels bewusst, also gibt es überhaupt keine Spur von Heiligkeit. Es ist eindeutig keine Predigt, sondern ein Kommentar, der einen Einblick mit geringer Steigung in eine sehr aktuelle Debatte bietet. Gut gemacht. Danke, Mike.
Ich sehe immer noch nicht die Logik hinter HTML/CSS-in-JS! Wenn wir unsere Worte zum Prinzip der Trennung der Belange zurücknehmen müssen, müssen wir auch unsere Worte zu allen anderen Design- und Entwicklungsprinzipien wie Inversion of Control, dem Single Responsibility Principle usw. zurücknehmen. Wenn es keinen Sinn ergibt, Dinge zu trennen, warum komponieren Sie dann? Warum ist eine monolithische Benutzeroberfläche nicht besser? Sehen Sie, es ist wirklich beschämend, dass selbst professionelle Entwickler gezwungen sind, eine Sache zu predigen, aber eine andere zu praktizieren! Oder vielleicht haben React-Entwickler nie wirklich etwas davon verstanden und den GRUND, warum wir überhaupt 3 verschiedene Technologien (HTML, CSS und JS) haben.
Ein gutes Framework ist eines, das die Entwicklung innerhalb der Sphären unseres Berufs erleichtert; eines, das es einfacher macht, das Richtige zu tun, und schwieriger, das Falsche zu tun. Es ist traurig, wie viele Entwickler sich in diesem Schlamassel verfangen haben. Ich kann mir kaum vorstellen, wie viele Web-Apps in diesem Code-Chaos erstellt wurden, wie sie derzeit überleben und wie viel Zeit und Ressourcen früher oder später benötigt werden, um sie auf Normalität umzuschreiben, da die Community jetzt „vernünftige“ UI-Frameworks wie CHTML (https://github.com/onephrase/chtml) begrüßt.
Ich stimme nicht zu. Nur weil wir experimentieren, eine Sache zu überdenken, heißt das nicht, dass wir alles überdenken müssen.
React unterscheidet zwischen Trennung von Technologie und Trennung von Belangen, das steht alles in ihrer Dokumentation. Es trennt den Zustand von der Ansichtsebene, behandelt aber alle Elemente der Ansichtsebene als Funktion des Zustands, was nicht nur logisch ist, man könnte argumentieren, dass wir nicht verstanden haben, was Trennung von Belangen vor React bedeutete.
Schauen Sie sich Frameworks vor React an. Sie trennen Technologien, was den Geltungsbereich beendet. Aber man braucht offensichtlich diese Technologien, um dynamisch zu sein, also wird der Geltungsbereich über DI wieder eingeführt und die Logik über Syntaxerweiterungen (for-each, if usw.) wieder eingeführt. Mit anderen Worten, sie trennen ohne Grund, nur um diese Teile mit massiver Komplexität wieder zusammenzukleben.
Die Verwendung von HTML @import zum Importieren von HTML-Dateien in andere HTML-Dateien ist React für mich.
Als Ein-Mann-Marketingberater werde ich manchmal in Full-Build-Website-Projekte hineingezogen, bei denen ich lückenhafte Fähigkeiten dehnen muss, um die Kundenanforderungen zu erfüllen. Auf gut geschriebene, meinungslose und zugängliche Inhalte wie diesen zu stoßen, ist ein Geschenk des Himmels.
Gut gemacht, Mike, du bist auf meiner Lesezeichenliste!
Vielen Dank an Sie und das CSS-Tricks-Team für diesen Artikel. Interessant, vernünftig, informativ. Deklarativ vs. Imperativ? Kleines Gehirn hier. wusste ich nicht. Habe etwas Neues gelernt. :thumbsup
Vielen Dank für diesen Überblick! Ich verstehe jetzt besser, wann und warum man HTML-in-JS-Frameworks verwendet, und dass sie ihre Vorteile haben. Ich habe auch gelernt, was ihr selektiver Zweck sein sollte und dass sie nicht dazu gedacht sind, HTML an sich abzulösen – hoffentlich lesen auch einige überenthusiastische Fans von React, Vue usw. Ihren Artikel.
Ich verstehe nicht, warum die Leute schreien, dass HTML in JavaScript seltsam ist … dieselben Leute haben HTML in PHP und anderen serverseitigen Vorlagensystemen verwendet, und um alles zu verderben, sagen sie, dass Vue, Angular oder Svelte besser sind, und sie nehmen sich nie die Zeit, die endgültige Ausgabe dieser Jungs zu überprüfen und festzustellen, dass es am Ende alles HTML in JavaScript ist.
Da muss ich Ihnen zustimmen. Zumindest verhindert JSX SQL-Injections durch Interpolieren von Benutzereingaben in String-Template-basiertes HTML ;)
Ausgezeichnete Erklärung der imperativen und deklarativen Programmierung, nach langer Zeit habe ich einen der besten Artikel gelesen.
Toller Artikel, ich versuche, das Unternehmen, für das ich arbeite, in ein deklarativeres JS-Framework zu drängen und habe Zeit bekommen, zu experimentieren. Ich habe mich in Angular verliebt, da es immer noch ein gewisses Maß an Trennung der Belange hat (wie separate Dateien für html, Styles und Typescript). Ich habe während dieses Experiments mit dem Rest meines Teams festgestellt, dass die anderen FE-Entwickler, die eher HTML- und SCSS-affin sind, einfacher an dem arbeiten können, was sie brauchen, als sie es mit React oder Vue könnten
Das ist definitiv ein starkes Argument für Angular und auch für Vue und Svelte. Ich denke, diese landen an einer anderen Stelle im Spektrum des Kompromisses hier, aber (rein meine Meinung) Reacts Vorhersagbarkeit und Ökosystem stellen es für mich vor diese, zumindest für ausreichend komplexe UIs. Es ist definitiv eine Entscheidung, die jedes Team basierend auf seinen eigenen Prioritäten und der anstehenden Aufgabe treffen sollte.
Persönlich bin ich sehr gespannt, was die Zukunft für Web Components bereithält, da sie in jedem dieser Frameworks verwendet werden könnten. Ich habe immer noch Probleme mit ihnen, aber sie bewegen sich in die richtige Richtung. Vielleicht handelt mein nächster Artikel davon!
React unterscheidet zwischen Trennung von Technologie und Trennung von Belangen, das steht alles in ihrer Dokumentation. Es trennt den Zustand von der Ansichtsebene, behandelt aber alle Elemente der Ansichtsebene als Funktion des Zustands, was nicht nur logisch ist, man könnte argumentieren, dass wir nicht verstanden haben, was Trennung von Belangen vor React bedeutete.
Schauen Sie sich Frameworks vor React an. Sie trennen Technologien, was den Geltungsbereich beendet. Aber man braucht offensichtlich diese Technologien, um dynamisch zu sein, also wird der Geltungsbereich über DI wieder eingeführt und die Logik über Syntaxerweiterungen (for-each, if usw.) wieder eingeführt. Mit anderen Worten, sie trennen ohne Grund, nur um diese Teile mit massiver Komplexität wieder zusammenzukleben.
Awesome article. Aptly described.
Vielen Dank für diesen "spoon-feeding" Artikel, Kumpel. Er fühlte sich sehr maßgeschneidert für mich an. Bis zu diesem Moment zögerte ich, diese JavaScript-frisst-HTML-Programmiermethode auszuprobieren, und war wütend darüber. Ich bin einer dieser Leute, die HTML, CSS und JS gerne getrennt halten, selbst in komplexen Anwendungen... Ich wusste, dass diese neuen Frameworks diese Methode änderten, aber es machte mich nur verrückt, wie warum!!!
Jeder Zentimeter meiner Unklarheit ist jetzt beseitigt, und ehrlich gesagt hast du mir einen zuversichtlichen Klaps auf die Schulter gegeben, wie ich diese neuen Frameworks betrachten sollte.
Was für ein großartiger Artikel. Du hast es absolut perfekt erklärt. Ich bin Full-Stack-Entwickler, aber ich habe mich unwohl gefühlt, HTML in JS zu packen. Ich habe das Gefühl, dass es ein evolutionärer Schritt ist, den wir sehr bald nicht mehr machen werden. Ich bin immer noch ein Purist, was das Frontend HTML/CSS/JS angeht. Aus all den oben genannten Gründen, die du erwähnt hast. Im Backend verwenden wir Teilansichten, so werden wiederverwendbare Single-Source-Komponenten erreicht. Was auf der Client-Seite geliefert wird, ist wirklich nur eine dynamische Antwort, aber der Client erhält eine reine Antwort. So viele Möglichkeiten, Code zu schneiden, oder!
Ausgezeichneter Beitrag! Ich finde es fast unmöglich, gute technische Artikel zu finden, die sich an Nicht-Experten richten (außer Tutorials, wohlgemerkt).
Meine Projekte waren in letzter Zeit zwischen der Verwendung von Vanilla HTML+js und reaktiven Tools aufgeteilt, und obwohl ich die praktischen Unterschiede gut verstehe, denke ich ständig: „Wie würde ich das jemandem erklären, für den das neu ist? Welchen Denkprozess müssten sie verstehen?“ Meine Antwort wäre jetzt, ihnen diesen Artikel zu schicken :)
Wirklich inspirierend. Das Web braucht mehr solche Artikel.
Meiner Meinung nach ist es eher eine Frage der Kurz- vs. Langfristigkeit, und was sinnvoller ist, hängt von deinem Fachgebiet ab und davon, wie viel du planen kannst oder willst. In diesem Bereich passiert so viel, weil es meiner Meinung nach keine native Mitte zwischen diesen Technologien gibt.
JS/React ändert sich schnell und ist kurzfristig flexibler, HTML und CSS sind stabiler, aber auch starrer. Es ist keine Überraschung, dass es Geld gibt, um eine goldene Mitte zu schaffen, indem JS stabiler und langfristig tragfähiger gemacht wird mit Frameworks (z.B. Gatsby), und HTML und CSS kurzfristig flexibler gemacht werden, indem Belange kombiniert werden (z.B. Kolokation von Stilen und Semantik in Tailwind).
Hallo Mike,
Schöner Artikel! Es ist lustig, ich habe gestern genau darüber nachgedacht. Ich bin auch Frontend-Entwickler, aber ich habe erst angefangen, mich wirklich intensiv mit JavaScript zu beschäftigen, als unser Unternehmen vor ein paar Jahren kopfüber in React eintauchte. All die "traditionellen" Frontendler wie ich wurden plötzlich in eine amorphe Welt von ES6, JSX, React und JavaScript gestürzt. Damals konnte ich den Unterschied zwischen vielem davon nicht erkennen.
Jetzt, wo ich mich sehr wohl fühle, komplexe React-Apps zu schreiben, habe ich darüber nachgedacht, wie schwer es wäre, dieselben zustandsbehafteten Apps mit Vanilla JS zu erstellen. Ich habe gestern tatsächlich ein jsfiddle einer Zähler-App erstellt. Was ich nicht in Worte fassen konnte, war, warum es ohne React nervig war. Ich glaube, du hast es für mich in einem anderen Kommentar zementiert, die Tatsache, dass React
Vielen Dank für diesen Artikel, es ist, als wäre er für mich geschrieben worden. Ich habe auch die Verweise auf die Jams der späten 90er/frühen 00er Jahre geschätzt!
P.S. Kleine Welt; ich war in deinem C++-Kurs in der High School. Dein Snake-Spiel war unwirklich. Ich hoffe, dir geht es gut. :)
Keine Gegenargumente, sondern aufrichtige Fragen
Wie verhält sich das in Bezug auf Barrierefreiheit? Funktioniert es mit Screenreadern? Viele Regierungs-Websites haben ziemlich definite Anforderungen an die Barrierefreiheit, und HTML funktioniert heutzutage ziemlich gut, selbst wenn es schlecht geschrieben ist. Ich schätze, dass JavaScript in Ordnung sein sollte, aber nur, wenn die Entwickler die Arbeit leisten, damit es korrekt funktioniert. Siehe https://webaim.org/techniques/javascript/
Wie wirkt sich das auf SEO aus? Google hat seinen Indexer (Caffeine) erst kürzlich aktualisiert, um eine aktuelle Version von Chrome zu verwenden. Und JavaScript-basierte Seiten werden zwangsläufig später/seltener indiziert als HTML-Seiten – HTML-Seiten sind einfach zu indizieren, JavaScript-Seiten erfordern, dass Code zuerst ausgeführt wird. Andere Suchmaschinen haben unterschiedliche Unterstützungsniveaus; einige sind blind für JavaScript. Siehe https://www.deepcrawl.com/knowledge/white-papers/javascript-seo-guide/how-javascript-rendering-works/
Persönlich mag ich es nicht, Inhalt und Code zu mischen – es macht es zu schwer, den Inhalt zu ändern –, aber ich baue ja auch CMSes beruflich...
„Wenn Webanwendungen komplexer werden, verursacht die Beibehaltung der klassischen Trennung der Belange zwischen HTML und JavaScript zunehmend schmerzhafte Kosten.“
„aber wenn dein ganzes JavaScript nur eine nicht-interaktive Webseite erstellt, solltest du kein JavaScript verwenden.“
Ja. Natürlich. Aber die Verletzung dieser Prinzipien ist der Grund, warum JS HTML „frisst“. Es gibt einen neuen Hammer (d.h. React) und jetzt ist ALLES ein Nagel. Was beunruhigend ist, ist die Voreingenommenheit, die in diese Entscheidungen einfließt. Das heißt, Entwickler/Ingenieure machen sich selbst zum Mittelpunkt anstelle des Kunden und/oder der Anwendung. Was könnte schiefgehen?
Großartige Sache. Ich betrachte mich selbst als Frontend-Minimalist und stimme daher in vielen Punkten vollkommen zu.
Eine Sache hat mich zum Nachdenken gebracht, die Beschriftung der Tabelle enthält einen Status mit angekreuzter Zahl zusammen mit zwei Schaltflächen.
Ist die Beschriftung nicht dazu gedacht, zu beschreiben, was die Tabelle tatsächlich ist, wie z.B. Zutatenliste oder Ähnliches? Ich meine, der Screenreader nimmt es auf und liest, was die Tabelle ist. Jetzt ist es eher eine Statusleiste mit Aktionen, und ich vermute, das wäre verwirrend?
Hmm. Es fühlt sich sehr nach XAML an, dem XML-Markup, das für die WPF/UWP/Xamarin (in leicht unterschiedlichen Dialekten) UI-Programmierung in .NET verwendet wird. Dein Code-Behind hat eine einzelne beobachtbare Sammlung von irgendwelchen Dingen, und der XAML-Code konstruiert deklarativ eine Ansicht dieser Sammlung, die gefiltert oder sortiert werden kann oder was auch immer, und dann als Listenfeld angewendet wird, oder als Elemente eines Kombinationsfelds, oder als Grundlage für die detailliertere Betrachtung des aktuell ausgewählten Eintrags usw. Und wenn sich das ursprüngliche Element in der beobachtbaren Sammlung ändert, ändert sich auch alles, was davon abhängt.
Es erfordert jedoch, dass vieles richtig verdrahtet wird, und das Debuggen, wenn die Bindung nicht so zugeordnet wird, wie du denkst, kann ein echtes Problem sein. Aber das Gesamtprinzip ist sehr ähnlich. Finde einen Weg, Vorlagen zum Laufen zu bringen, und du bist schon fast am Ziel.
Es wäre interessant, zu sehen, wie Dinge auf diese Weise mit HTML/Javascript erstellt werden. Verwende Attributwerte, um die Bindungen zu bestimmen, und lass das JS-Framework die Änderungen verfolgen.
Vorsicht: Es ist schon eine Weile her, dass ich JavaScript ernsthaft verwendet habe, und es könnte sein, dass es diese Art von Setup bereits handhaben kann. Es sieht nur so aus, als ob es noch nicht ganz so weit ist. Es wäre interessant, zu versuchen, ein solches System aufzubauen.
Toller Artikel, Mike!
Aus Neugier und um "das Publikum dieses Artikels so weit wie möglich zu erweitern" habe ich die Einkaufsliste mit Vue.js (von einem CDN) implementiert
Ich möchte hinzufügen, dass es nicht meine Absicht ist zu sagen, dass ein Framework besser ist als ein anderes, die Idee hier ist, den Leuten unterschiedliche Perspektiven zu geben, wie ein solches Ergebnis mit verschiedenen Tools erreicht werden kann.
Wow…
… Wo kaufst du ein, dass du genau 2 Eier kaufen kannst?
Absolut geliebt. Erstklassiges Schreiben, technisch und sehr informativ.
Das war ein großartiger Artikel. Das erste Mal, dass ich wirklich ein besseres Verständnis dafür bekommen habe, warum man ein Framework wie React verwenden sollte, abgesehen davon, dass jeder sagt, man sollte es tun, weil es einfach "besser" ist.
Ich mag Vanilla JS wirklich und ich lerne es immer noch und werde besser darin, und ich konnte die meisten Dinge damit gut erledigen, also war ich nicht motiviert, mich wirklich in ein Framework zu vertiefen und es zu lernen, aber dieser Artikel hat mir eine andere Perspektive gegeben.
Und das ist lustig mit dem CSS-In-JS :-) Da bin ich noch nicht ganz so weit. Ich genieße mein SCSS voll und ganz.
Zumindest verhindert JSX SQL-Injections, indem es Benutzereingaben in String-Template-basiertes HTML interpoliert ;)
Das ist einfach unglaublich! Danke, freue mich auf die Fortsetzungen.
Wenn du weitere Informationen darüber suchst, welche JavaScript-Frameworks du wählen solltest, gibt es einen nützlichen Artikel zu diesem Thema: https://www.ideamotive.co/blog/consider-these-javascript-frameworks-to-be-more-valuable-on-a-job-market
Dort kannst du über Svelte, TypeScript, GraphQL, NestJS, Gatsby, NextJS und Immer lesen.
Hallo! Es ist ein großartiger Artikel, ich stimme zu, dass HTML eine Standard-Auszeichnungssprache ist, die die primäre Struktur einer Website bereitstellt, während JavaScript eine fortgeschrittene Programmiersprache ist, die Webseiten interaktiver und dynamischer macht. Wenn du ein Webentwickler werden willst, der schnell Websites erstellen kann, dann ist ein gutes Wissen über JavaScript und verschiedene, beliebte JavaScript-Webentwicklungs-Frameworks sehr wichtig für deinen Produktentwicklungsprozess (PDP) Du kannst dort Informationen über Technologien finden, die eine kluge Wahl für deine Minimum Viable Product Software sein könnten.