React & Co.: Unterschied zwischen den Versionen

Aus Jonas Notizen Webseite
Zur Navigation springen Zur Suche springen
(Texte marginal verbessert (TODO))
Zeile 1: Zeile 1:
 
[[Datei:React-icon.svg|mini|200x200px|Offizielles ReactJS-Icon]]
 
[[Datei:React-icon.svg|mini|200x200px|Offizielles ReactJS-Icon]]
React ist '''die''' JavaScript-Bibliothek von Facebook, die sich zu einer sehr beliebten Technologie zur Erstellung dynamischer, testbarer und performanter Benutzeroberflächen entwickelt hat. Obwohl es kein vollwertiges Framework wie Angular oder Ember ist, ist React aufgrund seiner '''Konzentration auf funktionale komponentenbasierte Ansichten''' ohne (oder '''minimalen''') '''internen Zustand''' '''eine gute Wahl für die Erstellung von Einzelseitenanwendungen (SPA)''' oder sogar dynamischen Unterkomponenten innerhalb einer seitenbasierten Anwendung.<br />
+
React ist eine JavaScript-Bibliothek von Facebook, die sich zu einer sehr beliebten Technologie '''für die''' '''Erstellung dynamischer''', testbarer und performanter '''Benutzeroberflächen''' entwickelt hat. Obwohl es kein vollwertiges Framework (Grundgerüst) wie Angular oder Ember ist, ist React aufgrund seiner '''Konzentration auf funktionale komponenten-basierte Ansichten''' ohne (oder '''minimalen''') '''internen Zustand''' '''eine gute Wahl für die Erstellung von Einzelseitenanwendungen (SPA)''' oder sogar dynamischen Unterkomponenten innerhalb einer seiten-basierten Anwendung.<br />
  
 
=React Einführung - Kernkonzepte=
 
=React Einführung - Kernkonzepte=
  
Das Modell von React verspricht durch die '''Konzepte des unidirektionalen Datenflusses und des „Virtual DOM“''' den einfachen, aber trotzdem hochperformanten Aufbau auch komplexer Anwendungen.<br />
+
Das Modell von React verspricht durch die '''Konzepte des unidirektionalen Datenflusses und des „Virtual DOM“''' den einfachen, aber trotzdem hochperformanten Aufbau auch komplexer Anwendungen.
  
 
==Keine vollständige Anwendungsbibliothek==
 
==Keine vollständige Anwendungsbibliothek==
 
Da sich React nur mit dem Rendern von Daten an das DOM befasst, erfordert die Erstellung von React-Anwendungen in der Regel die Verwendung zusätzlicher Bibliotheken, wie z.B. für die [[wikipedia:State_management|(globale) Zustandsverwaltung]] (State-Management) und das Routing. [https://de.wikipedia.org/wiki/Redux_(JavaScript-Bibliothek) Redux] und [https://reactrouter.com/ React Router] sind entsprechende Beispiele für solche Bibliotheken. <ref>[[wikipedia:React_(web_framework)|Englischer Wikipedia-Eintrag zu "React"]]</ref>
 
Da sich React nur mit dem Rendern von Daten an das DOM befasst, erfordert die Erstellung von React-Anwendungen in der Regel die Verwendung zusätzlicher Bibliotheken, wie z.B. für die [[wikipedia:State_management|(globale) Zustandsverwaltung]] (State-Management) und das Routing. [https://de.wikipedia.org/wiki/Redux_(JavaScript-Bibliothek) Redux] und [https://reactrouter.com/ React Router] sind entsprechende Beispiele für solche Bibliotheken. <ref>[[wikipedia:React_(web_framework)|Englischer Wikipedia-Eintrag zu "React"]]</ref>
 
<br />
 
  
 
==Unidirektionaler Datenfluss==
 
==Unidirektionaler Datenfluss==
 
Anders als UI-Frameworks wie Angular verzichtet React bewusst auf eine bidirektionale Datenbindung. An deren Stelle tritt der unidirektionale Datenfluss, bei dem Daten stets nur in einer Richtung übergeben werden.
 
Anders als UI-Frameworks wie Angular verzichtet React bewusst auf eine bidirektionale Datenbindung. An deren Stelle tritt der unidirektionale Datenfluss, bei dem Daten stets nur in einer Richtung übergeben werden.
  
Was zunächst nach einer gravierenden Einschränkung klingt, stellt sich tatsächlich als Bereicherung dar. Der unidirektionale Datenfluss erhöht nämlich die Nachvollziehbarkeit, wie Daten innerhalb der Anwendung verteilt und verarbeitet werden. Das erleichtert die Analyse und bei Bedarf die Fehlersuche.
+
Was zunächst nach einer gravierenden Einschränkung klingt, stellt sich tatsächlich als Bereicherung dar. Der unidirektionale Datenfluss '''erhöht''' nämlich die '''Nachvollziehbarkeit''', wie Daten innerhalb der Anwendung verteilt und verarbeitet werden. Das erleichtert die Analyse und bei Bedarf die Fehlersuche.
 
 
<br />
 
  
 
==[https://de.reactjs.org/docs/components-and-props.html Komponenten]==
 
==[https://de.reactjs.org/docs/components-and-props.html Komponenten]==
<u>React-Komponenten sind kleine, wiederverwendebare Codestücke, die ein zu renderndes React-Element an die Seite zurückgeben.</u> <ref name=":0">[https://de.reactjs.org/docs/glossary.html Glossar der React Begriffe]</ref> Komponenten werden in React '''hierarchisch''' aufgebaut und können in dessen Syntax als selbst definierte HTML-Tags repräsentiert werden.
+
<u>React-Komponenten sind kleine, wiederverwende-bare Codestücke, die ein zu renderndes React-Element zurückgeben.</u> <ref name=":0">[https://de.reactjs.org/docs/glossary.html Glossar der React Begriffe]</ref> Komponenten werden in React '''hierarchisch''' aufgebaut und können in dessen Syntax als selbst definierte HTML-Tags repräsentiert werden.
  
 
Vom Konzept her sind Komponenten wie JavaScript-Funktionen. Sie akzeptieren beliebige Eingaben (readonly “[https://de.reactjs.org/docs/components-and-props.html props]” genannnt) und geben React-Elemente zurück, welche beschreiben was auf dem Bildschirm angezeigt werden soll. Der einfachste Weg eine Komponente zu definieren, ist eine JavaScript-Funktion zu schreiben:<syntaxhighlight lang="javascript">
 
Vom Konzept her sind Komponenten wie JavaScript-Funktionen. Sie akzeptieren beliebige Eingaben (readonly “[https://de.reactjs.org/docs/components-and-props.html props]” genannnt) und geben React-Elemente zurück, welche beschreiben was auf dem Bildschirm angezeigt werden soll. Der einfachste Weg eine Komponente zu definieren, ist eine JavaScript-Funktion zu schreiben:<syntaxhighlight lang="javascript">
Zeile 32: Zeile 28:
 
}
 
}
 
</syntaxhighlight>Komponenten können in mehrere kleinere Teile zerlegt und deren Funktionialität in anderen Komponenten wiederverwendet werden. Komponenten können andere Komponenten, Arrays, Strings und Nummern zurückgeben.
 
</syntaxhighlight>Komponenten können in mehrere kleinere Teile zerlegt und deren Funktionialität in anderen Komponenten wiederverwendet werden. Komponenten können andere Komponenten, Arrays, Strings und Nummern zurückgeben.
<br />
 
 
 
===Kritik am Komponenten-zentrierten Modell von React===
 
===Kritik am Komponenten-zentrierten Modell von React===
 
Anders als bei strikten MVC-Modellen wird in React ein komponentenzentriertes Modell vorgeschlagen, welches Logik für Interaktion und Darstellung innerhalb eines Objekts bündelt ([[wikipedia:Separation_of_concerns|Seperation of Concerns]]). Dies wird insbesondere aufgrund der weitverbreiteten strikten Trennung zwischen Markup und Logik in Form von Templating-Systemen oft kritisch gesehen. <ref name=":1">[https://de.wikipedia.org/wiki/React#Kritik Deutscher Wikipedia-Eintrag zu "React": Kritik]</ref>
 
Anders als bei strikten MVC-Modellen wird in React ein komponentenzentriertes Modell vorgeschlagen, welches Logik für Interaktion und Darstellung innerhalb eines Objekts bündelt ([[wikipedia:Separation_of_concerns|Seperation of Concerns]]). Dies wird insbesondere aufgrund der weitverbreiteten strikten Trennung zwischen Markup und Logik in Form von Templating-Systemen oft kritisch gesehen. <ref name=":1">[https://de.wikipedia.org/wiki/React#Kritik Deutscher Wikipedia-Eintrag zu "React": Kritik]</ref>
<br />
+
 
 
==[https://de.reactjs.org/docs/rendering-elements.html Darstellungselemente] (!= Komponenten)==
 
==[https://de.reactjs.org/docs/rendering-elements.html Darstellungselemente] (!= Komponenten)==
 
React-Elemente sind die Bausteine von React-Anwendungen. Elemente könnten mit dem allgemein bekannteren Konzept der “Komponenten” verwechselt werden. '''<u>Ein Element beschreibt was man auf dem Bildschirm sehen möchtest.</u>''' <u>'''React-Elemente sind unveränderbar.'''</u>
 
React-Elemente sind die Bausteine von React-Anwendungen. Elemente könnten mit dem allgemein bekannteren Konzept der “Komponenten” verwechselt werden. '''<u>Ein Element beschreibt was man auf dem Bildschirm sehen möchtest.</u>''' <u>'''React-Elemente sind unveränderbar.'''</u>
Zeile 45: Zeile 39:
 
==[https://reactjs.org/docs/faq-internals.html Virtual DOM] und [https://de.reactjs.org/docs/reconciliation.html DOM-Diffing]==
 
==[https://reactjs.org/docs/faq-internals.html Virtual DOM] und [https://de.reactjs.org/docs/reconciliation.html DOM-Diffing]==
 
[[Datei:ReactJS-Decisive Element Rendering.gif|mini|287x287px|Offizielles React-Beispiel zum Thema DOM-Diffing]]
 
[[Datei:ReactJS-Decisive Element Rendering.gif|mini|287x287px|Offizielles React-Beispiel zum Thema DOM-Diffing]]
Die Kernidee von React besteht in der Annahme, dass der komplette, der betroffenen Komponente untergeordnete Anwendungsbaum bei jeder Änderung einer Eigenschaft der Komponente neu aufgebaut wird. Da es in der Praxis rechenintensiv sein kann, dies z. B. im Webbrowser innerhalb des DOM durchzuführen, wurde das Konzept des „Virtual DOM“ geschaffen. <ref name=":1" />
+
Die '''Kernidee von React''' besteht in der Annahme, dass der komplette, der betroffenen Komponente untergeordnete Anwendungsbaum bei jeder Änderung einer Eigenschaft der Komponente neu aufgebaut wird. Da es in der Praxis rechenintensiv sein kann, dies z. B. im Webbrowser innerhalb des DOM durchzuführen, wurde das Konzept des „Virtual DOM“ geschaffen. <ref name=":1" />
  
 
Die damit verbundene Technik des „DOM-Diffing“ beschreibt das selektive Aktualisieren des DOM auf Basis eines Vergleichs zwischen ursprünglichem und geändertem Virtual DOM.         
 
Die damit verbundene Technik des „DOM-Diffing“ beschreibt das selektive Aktualisieren des DOM auf Basis eines Vergleichs zwischen ursprünglichem und geändertem Virtual DOM.         
Zeile 53: Zeile 47:
  
 
React [https://de.reactjs.org/docs/react-without-jsx.html benötigt kein JSX], aber die Meisten empfinden es als hilfreiches Werkzeug, wenn sie in JavaScript-Code an der UI arbeiten. Zusätzlich bietet es React die Möglichkeit, bessere Fehlermeldungen und Warnungen anzuzeigen.
 
React [https://de.reactjs.org/docs/react-without-jsx.html benötigt kein JSX], aber die Meisten empfinden es als hilfreiches Werkzeug, wenn sie in JavaScript-Code an der UI arbeiten. Zusätzlich bietet es React die Möglichkeit, bessere Fehlermeldungen und Warnungen anzuzeigen.
 
<br />
 
 
===JSX ist auch ein Ausdruck===
 
===JSX ist auch ein Ausdruck===
 
Jedes JSX Element ist eigentlich nur “syntactic sugar” für den Aufruf von <code>React.createElement(component, props, ...children)</code>. Dementsprechend kannst du alles, was mit JSX möglich ist, auch in einfachem Javascript umsetzen. Siehe folgende Tabelle als Beispiel:
 
Jedes JSX Element ist eigentlich nur “syntactic sugar” für den Aufruf von <code>React.createElement(component, props, ...children)</code>. Dementsprechend kannst du alles, was mit JSX möglich ist, auch in einfachem Javascript umsetzen. Siehe folgende Tabelle als Beispiel:
Zeile 184: Zeile 176:
  
 
==Eine simple React-App-Entwicklungsumgebung Schritt-für-Schritt selbst aufsetzen==
 
==Eine simple React-App-Entwicklungsumgebung Schritt-für-Schritt selbst aufsetzen==
Quellen: [https://blog.usejournal.com/creating-a-react-app-from-scratch-f3c693b84658 "Creating a React-App.. From Scratch" (Medium)], [https://reactjs.org/docs/create-a-new-react-app.html "Creating a New React App" (React-Doc)], [https://objectcomputing.com/news/2016/05/28/using-react-grails "Using React with Grails" (ObjectComputing)]
+
Quellen (Ich bin schlecht in Schritt-für-Schritt Tutorials ohne zu viele Kenntnisse vorauszusetzen): [https://blog.usejournal.com/creating-a-react-app-from-scratch-f3c693b84658 "Creating a React-App.. From Scratch" (Medium)], [https://reactjs.org/docs/create-a-new-react-app.html "Creating a New React App" (React-Doc)], [https://objectcomputing.com/news/2016/05/28/using-react-grails "Using React with Grails" (ObjectComputing)]
 
 
  
React funktioniert nicht "einfach so". Es verwendet Schlüsselwörter und einen Syntax mit dem Node nichts anfangen kann (z.B. die Schlüsselwörter <code>import</code> und <code>export</code>, oder der JSX-Syntax). Es erfordert eine ziemlich umständliche Einrichtung, und Facebook hat mit "Create-React-App" eine Option bereitgestellt, die das Starten einer React-Anwendung einfach macht.
 
  
Warum sich dann die Mühe machen? Die Sache ist die, dass "Create-React-App" vieles von dem abstrahiert, was eine React-App überhaupt im Browser funktionieren lässt. <u>Es gibt eine Reihe von Gründen warum man vielleicht eine eigene Implementierung machen will, oder zu-mindestens verstehen will welche Komponente im Prozess für was eigentlich zuständig ist.</u>
+
React funktioniert nicht "einfach so". Es verwendet Schlüsselwörter und einen Syntax mit dem NodeJS nichts anfangen kann (z.B. die Schlüsselwörter <code>import</code> und <code>export</code>, oder der JSX-Syntax). Es erfordert eine ziemlich umständliche Einrichtung, und Facebook hat mit "Create-React-App" eine Option bereitgestellt, die das Starten einer React-Anwendung einfach macht.  
  
<br />
+
Warum sich dann die Mühe machen? Die Sache ist die, dass "Create-React-App" vieles von dem abstrahiert, was eine "React-App" überhaupt im Browser funktionieren lässt. <u>Es gibt eine Reihe von Gründen warum man vielleicht eine eigene Implementierung machen will, oder zu-mindestens verstehen will welche Komponente im Prozess für was eigentlich zuständig ist.</u>
  
 
===<u>Bestandteile einer typischen JavaScript Build Werkzeugkette</u>===
 
===<u>Bestandteile einer typischen JavaScript Build Werkzeugkette</u>===
Zeile 204: Zeile 194:
  
 
===Setup===
 
===Setup===
Um zu beginnen erstellt man ein neues Verzeichnis für die React-Anwendung.
+
Erstelle ein neues Verzeichnis für die React-Anwendung und öffne diesen Ordner in einem Terminal.
  
Als erstes initialisiert man das Verzeichnis wie jedes neues Node-basiertes Projekt mit dem Befehl <code>npm init</code>.
+
Diesen Ordner markieren wir als den Root-Pfad für eine neue Node-Anwendung mit dem Befehl <code>npm init</code>.
  
 
*Falls man keine aktuelle Version der Node/NPM-SDK auf seinem System installiert hat, empfehle ich dringend <code>[https://github.com/creationix/nvm nvm]</code> (Es ist wie <code>sdkman</code>, aber für node/npm - Ein Tool zum installieren/managen von SDKs mithilfe einer einfach Kommandozeilenumgebung).
 
*Falls man keine aktuelle Version der Node/NPM-SDK auf seinem System installiert hat, empfehle ich dringend <code>[https://github.com/creationix/nvm nvm]</code> (Es ist wie <code>sdkman</code>, aber für node/npm - Ein Tool zum installieren/managen von SDKs mithilfe einer einfach Kommandozeilenumgebung).
Zeile 216: Zeile 206:
 
   +-- index.html
 
   +-- index.html
 
  +-- src
 
  +-- src
Unser <code>public</code>-Verzeichnis verwaltet alle statischen Assets und beherbergt vor allem unsere <code>index.html</code>-Datei, die als Einstiegspunkt unserer Anwendung für den Browser dient. Sie können das folgende HTML-Markup in eine neue Datei <code>index.html</code> innerhalb des <code>public</code>-Verzeichnisses kopieren:<syntaxhighlight lang="html" line="1">
+
Unser <code>public</code>-Verzeichnis verwaltet alle statischen Assets und beherbergt vor allem unsere <code>index.html</code>-Datei, die als Einstiegspunkt unserer Anwendung für den Browser dient. Sie sieht wie folgt aus:<syntaxhighlight lang="html" line="1">
 
<!DOCTYPE html>
 
<!DOCTYPE html>
 
<html>
 
<html>
Zeile 248: Zeile 238:
 
</body>
 
</body>
 
</html>
 
</html>
</syntaxhighlight>Jetzt, wo wir unsere HTML-Seite eingerichtet haben, können wir anfangen, ernsthaft zu werden. Wir müssen noch ein paar weitere Dinge einrichten. Zunächst müssen wir sicherstellen, dass der Code, den wir schreiben, kompiliert werden kann.  
+
</syntaxhighlight>Jetzt, wo wir unsere HTML-Seite eingerichtet haben, können wir anfangen, ernsthaft zu werden. Zunächst müssen wir sicherstellen, dass der Code, den wir schreiben, kompiliert werden kann.  
  
 
===Installieren der benötigten NPM-Pakete===
 
===Installieren der benötigten NPM-Pakete===
Zeile 267: Zeile 257:
 
===Babel===
 
===Babel===
 
[[Datei:Babel Logo.svg|mini|180x180px|BabelJS Logo]]
 
[[Datei:Babel Logo.svg|mini|180x180px|BabelJS Logo]]
Da wir zum Schreiben unserer Komponenten JSX verwenden werden, müssen wir außerdem einen '''<u>Transpiler</u>''' verwenden, um unseren React-Code in "Plain Vanilla"-Javascript umzuwandeln. Moderne Javascript-Frameworks bewegen sich viel schneller als Web-Browser, und viele der Javascript-APIs, die häufig in React-Projekten verwendet werden, sind noch nicht Standard in Browsern.
+
Da wir zum Schreiben unserer Komponenten JSX verwenden werden, müssen wir außerdem einen '''<u>Transpiler</u>''' verwenden, um unseren React-Code in "Plain Vanilla"-Javascript für den Browser umzuwandeln. Moderne Javascript-Frameworks bewegen sich viel schneller als Web-Browser, und viele der Javascript-APIs die häufig in React-Projekten verwendet werden sind noch nicht Standard in Browsern. '''[https://babeljs.io/ babel]''' ist ein sehr beliebter und einfach-erweiterbarer Transpiler.
  
'''[https://babeljs.io/ babel]''' ist ein beliebter Transpiler mit vielen "Voreinstellungen", die verschiedene Versionen der Javascript-Syntax verstehen und transpilieren können.
+
Da Babel sehr vielseitig ist müssen wir eine kleine Grundkonfiguration einrichten. Ohne Plugin versteht der babel-Transpiler auch nur so-gut-wie Plain-JavaScript Syntax. Damit babel auch neuere Versionen von JavaScript sowie den JSX-Syntax verstehen und transformieren kann, müssen wir entsprechende Plugins hinzufügen.
  
Um diese Voreinstellungen zu aktivieren erstellt man im Stammverzeichnis des Node-Projekts eine <code>.babelrc</code>-Datei mit diesem Inhalt:<syntaxhighlight lang="json">
+
Die Babel-Konfiguration wird vorzugsweise in der Datei <code>.babelrc</code> im Stammverzeichnis des Node-Projekts vorgenommen. Sie kann wie folgt aussehen:<syntaxhighlight lang="json">
 
{
 
{
 
   "presets": [
 
   "presets": [
Zeile 278: Zeile 268:
 
   ]
 
   ]
 
}
 
}
</syntaxhighlight>Wenn wir unseren Code durch einen Transpiler laufen lassen wollen, bedeutet das, dass wir einen "Build"-Schritt brauchen, um die Arbeit zu erledigen:
+
</syntaxhighlight>
 
 
 
===Webpack===
 
===Webpack===
 
[[Datei:Webpack.png|mini|201x201px|Webpack Logo]]
 
[[Datei:Webpack.png|mini|201x201px|Webpack Logo]]
Zeile 309: Zeile 298:
 
|}
 
|}
 
Webpack ist ein sehr mächtiges, hoch-modulares Werkzeug um solche Bündel zu erstellen. '''Loader''' kümmern sich um die Kompilierung bestimmter Dateitypen für webpack. <code>babel-loader</code> ist zum Beispiel ein loader für JavaScript-Dateien.
 
Webpack ist ein sehr mächtiges, hoch-modulares Werkzeug um solche Bündel zu erstellen. '''Loader''' kümmern sich um die Kompilierung bestimmter Dateitypen für webpack. <code>babel-loader</code> ist zum Beispiel ein loader für JavaScript-Dateien.
 
 
  
 
Erstelle eine neue Datei im Stammverzeichnis des Projekts mit dem Namen <code>webpack.config.js</code>. Diese Datei exportiert ein Objekt mit der Konfiguration von webpack.<syntaxhighlight lang="javascript">
 
Erstelle eine neue Datei im Stammverzeichnis des Projekts mit dem Namen <code>webpack.config.js</code>. Diese Datei exportiert ein Objekt mit der Konfiguration von webpack.<syntaxhighlight lang="javascript">
 +
// As this is run by NodeJS, it only supports CommonJS Syntax for importing
 
const path = require("path");
 
const path = require("path");
 
const webpack = require("webpack");
 
const webpack = require("webpack");

Version vom 30. November 2020, 21:19 Uhr

Offizielles ReactJS-Icon

React ist eine JavaScript-Bibliothek von Facebook, die sich zu einer sehr beliebten Technologie für die Erstellung dynamischer, testbarer und performanter Benutzeroberflächen entwickelt hat. Obwohl es kein vollwertiges Framework (Grundgerüst) wie Angular oder Ember ist, ist React aufgrund seiner Konzentration auf funktionale komponenten-basierte Ansichten ohne (oder minimalen) internen Zustand eine gute Wahl für die Erstellung von Einzelseitenanwendungen (SPA) oder sogar dynamischen Unterkomponenten innerhalb einer seiten-basierten Anwendung.

React Einführung - Kernkonzepte

Das Modell von React verspricht durch die Konzepte des unidirektionalen Datenflusses und des „Virtual DOM“ den einfachen, aber trotzdem hochperformanten Aufbau auch komplexer Anwendungen.

Keine vollständige Anwendungsbibliothek

Da sich React nur mit dem Rendern von Daten an das DOM befasst, erfordert die Erstellung von React-Anwendungen in der Regel die Verwendung zusätzlicher Bibliotheken, wie z.B. für die (globale) Zustandsverwaltung (State-Management) und das Routing. Redux und React Router sind entsprechende Beispiele für solche Bibliotheken. [1]

Unidirektionaler Datenfluss

Anders als UI-Frameworks wie Angular verzichtet React bewusst auf eine bidirektionale Datenbindung. An deren Stelle tritt der unidirektionale Datenfluss, bei dem Daten stets nur in einer Richtung übergeben werden.

Was zunächst nach einer gravierenden Einschränkung klingt, stellt sich tatsächlich als Bereicherung dar. Der unidirektionale Datenfluss erhöht nämlich die Nachvollziehbarkeit, wie Daten innerhalb der Anwendung verteilt und verarbeitet werden. Das erleichtert die Analyse und bei Bedarf die Fehlersuche.

Komponenten

React-Komponenten sind kleine, wiederverwende-bare Codestücke, die ein zu renderndes React-Element zurückgeben. [2] Komponenten werden in React hierarchisch aufgebaut und können in dessen Syntax als selbst definierte HTML-Tags repräsentiert werden.

Vom Konzept her sind Komponenten wie JavaScript-Funktionen. Sie akzeptieren beliebige Eingaben (readonly “props” genannnt) und geben React-Elemente zurück, welche beschreiben was auf dem Bildschirm angezeigt werden soll. Der einfachste Weg eine Komponente zu definieren, ist eine JavaScript-Funktion zu schreiben:

function Welcome(props) {
  return <h1>Hallo, {props.name}</h1>;
}

Komponenten können ebenso als ES6-Klassen definiert werden:

class Welcome extends React.Component {
  render() {
    return <h1>Hallo, {this.props.name}</h1>;
  }
}

Komponenten können in mehrere kleinere Teile zerlegt und deren Funktionialität in anderen Komponenten wiederverwendet werden. Komponenten können andere Komponenten, Arrays, Strings und Nummern zurückgeben.

Kritik am Komponenten-zentrierten Modell von React

Anders als bei strikten MVC-Modellen wird in React ein komponentenzentriertes Modell vorgeschlagen, welches Logik für Interaktion und Darstellung innerhalb eines Objekts bündelt (Seperation of Concerns). Dies wird insbesondere aufgrund der weitverbreiteten strikten Trennung zwischen Markup und Logik in Form von Templating-Systemen oft kritisch gesehen. [3]

Darstellungselemente (!= Komponenten)

React-Elemente sind die Bausteine von React-Anwendungen. Elemente könnten mit dem allgemein bekannteren Konzept der “Komponenten” verwechselt werden. Ein Element beschreibt was man auf dem Bildschirm sehen möchtest. React-Elemente sind unveränderbar.

Normalerweise werden Elemente nicht direkt verwendet, sondern von Komponenten zurückgegeben. [2]

const element = <h1>Hallo, Welt</h1>;

Anders als die DOM Elemente eines Browsers, sind React Elemente schlichte kosten-effektive Objekte. React DOM kümmert sich um das Aktualisieren des DOMs und den dazugehörigen React Elementen.

Virtual DOM und DOM-Diffing

Offizielles React-Beispiel zum Thema DOM-Diffing

Die Kernidee von React besteht in der Annahme, dass der komplette, der betroffenen Komponente untergeordnete Anwendungsbaum bei jeder Änderung einer Eigenschaft der Komponente neu aufgebaut wird. Da es in der Praxis rechenintensiv sein kann, dies z. B. im Webbrowser innerhalb des DOM durchzuführen, wurde das Konzept des „Virtual DOM“ geschaffen. [3]

Die damit verbundene Technik des „DOM-Diffing“ beschreibt das selektive Aktualisieren des DOM auf Basis eines Vergleichs zwischen ursprünglichem und geändertem Virtual DOM.

JavaScript Syntax Extension (JSX)

JSX ist eine Syntaxerweiterung für JavaScript. Es ist ähnlich einer Template-Sprache, hat aber den vollen Leistungsumfang von JavaScript. [2]

React benötigt kein JSX, aber die Meisten empfinden es als hilfreiches Werkzeug, wenn sie in JavaScript-Code an der UI arbeiten. Zusätzlich bietet es React die Möglichkeit, bessere Fehlermeldungen und Warnungen anzuzeigen.

JSX ist auch ein Ausdruck

Jedes JSX Element ist eigentlich nur “syntactic sugar” für den Aufruf von React.createElement(component, props, ...children). Dementsprechend kannst du alles, was mit JSX möglich ist, auch in einfachem Javascript umsetzen. Siehe folgende Tabelle als Beispiel:

Originaler JSX-Code Mit Babel kompilierter JavaScript-Code (Siehe den offiziellen & interaktiven Online Babel-Compiler um "eigene Beispiele zu testen")
 1 class Hello extends React.Component {
 2   render() {
 3     return <div>Hello {this.props.toWhat}</div>;
 4   }
 5 }
 6 
 7 ReactDOM.render
 8   <Hello toWhat="World" />,
 9   document.getElementById('root')
10 );
1 class Hello extends React.Component {
2   render() {
3     return /*#__PURE__*/React.createElement("div", null, "Hello ", this.props.toWhat);
4   }
5 }
6 
7 ReactDOM.render( /*#__PURE__*/React.createElement(Hello, {
8   toWhat: "World"
9 }), document.getElementById('root'));

Nach dem Kompilieren werden JSX Ausdrücke als normale JavaScript-Funktionssaufrufe und als JavaScript-Objekte ausgewertet.

Das bedeutet, dass man JSX innerhalb von if-Blöcken und for-Schleifen verwenden, Variablen zuweisen, als Argument entgegennehmen oder aus einer Funktion zurückgeben kann.

JavaScript-Ausdrücke in JSX

Jeder valide JavaScript Ausdruck ist zwischen den geschweiften Klammern in JSX erlaubt. Zum Beispiel, 2 + 2, user.firstName, oder formatName(user) sind völlig valide JavaScript Ausdrücke.

Attribute in JSX festlegen

Attribute eines Tags/Elements werden wie in HTML/XML definiert, mit der Ausnahme dass man entweder String-Literale als Wert oder auch jeden validen JavaScript-Ausdruck mithilfe von den genannten Schweiften Klammern angeben kann:

// prop-Angabe mit einem String-Literal
const element = <div tabIndex="0"></div>;
// prop-Angabe mit einem JavaScript-Ausdruck
const element = <img src={user.avatarUrl}></img>;

Folgende Regeln gilt es zu beachten:

  • Setze keine Anführungszeichen um geschweifte Klammern um JavaScript-Ausdrücke in ein Attribut einzubinden. Benutze entweder Anführungszeichen (für Strings) oder geschweifte Klammern (für Ausdrücke) aber nicht beides zusammen im selben Attribut.
  • Da JSX näher an JavaScript als an HTML ist, verwendet React DOM camelCase als Namenskonvention für Eigenschaften anstelle der für HTML typischen schreibweise.
    • class wird in JSX zum Beispiel zu className, und tabindex zu tabIndex.


Kind-Elemente mit JSX angeben

Ist ein Element leer, kannst du es wie in XML mit /> schließen:

const element = <img src={user.avatarUrl} />;

JSX-Tags können Kind-Elemente enthalten:

const element = (
  <div>
    <h1>Hallo!</h1>
    <h2>Schön dich hier zu sehen.</h2>
  </div>
);

children prop

In den React-Dokumenten heißt es, dass props.children für Komponenten verwendet werden können, die "allgemeine Schachteln" darstellen und die "ihre Kinder-Elemente nicht im Voraus kennen". Das heißt dass eine Komponente im Normalfall keine Annahmen darüber machen sollte, was für ein Wert in props.children gefüttert wird - sie soll es einfach nur einbauen.

Im folgenden Beispiel bekommt die h1-Komponente 2 props übergeben:

  • className mit dem Wert "greeting" (String-Literal)
  • children mit dem Wert "Hallo Welt!" (String-Literal)
const element = (
  <h1 className="greeting">
    {/* Hier kann so gut wie alles drinnen stehen. (JavaScript-Ausdrücke die React-Elemente wiedergeben, ...)*/}
    Hallo Welt!
  </h1>
);

Im Prinzip entsteht daraus das folgende Objekt:

// Hinweis: Dies ist eine vereinfachte Struktur
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hallo Welt!'
  }
};


Komponenten-State und Lifecycle


Event Handhabung


Bedingte Darstellung


Formulare


State anheben


React Einführung - Weiteres


React Einführung - React-App-Entwicklung

Erstellen einer React-Anwendung

Das React Team empfiehlt bevorzugt diese Lösungen: [4]

  • Wenn man React lernt oder eine neue Single Page Anwendung erstellen will, hilft einem Create React App.
    • Create React App ist ein Open-Source npm-Skript dass einem automatisch eine vollständig funktionsfähige Entwicklungsumgebung für neue React-SPAs aufsetzt. Die verwendeten Entwicklungs-Toolchains sind der Compiler Babel und der Bundler webpack.
  • Wenn du eine vom Server gerenderte Webseite mit Node.js baust, dann probier Next.js.
    • Next.js ist ein beliebtes und leichtgewichtiges Framework für statische und server-gerenderte Anwendungen, die mit React erstellt wurden. Es enthält sofort einsatzbereite Styling- und Routing-Lösungen und setzt voraus, dass man Node.js als Serverumgebung verwendet.
  • Wenn du eine statische auf Inhalt orientierte Webseite baust, dann probier Gatsby.
    • Gatsby ist der beste Weg, statische Websites mit React zu erstellen. Es ermöglicht die Verwendung von React-Komponenten, gibt aber vorgerendertes HTML und CSS aus, um die schnellste Ladezeit zu garantieren.
  • Wenn du eine Komponentenbibliothek baust oder mit einer existierenden Codebasis integrierst, dann probiere flexiblere Werkzeuge:


Eine simple React-App-Entwicklungsumgebung Schritt-für-Schritt selbst aufsetzen

Quellen (Ich bin schlecht in Schritt-für-Schritt Tutorials ohne zu viele Kenntnisse vorauszusetzen): "Creating a React-App.. From Scratch" (Medium), "Creating a New React App" (React-Doc), "Using React with Grails" (ObjectComputing)


React funktioniert nicht "einfach so". Es verwendet Schlüsselwörter und einen Syntax mit dem NodeJS nichts anfangen kann (z.B. die Schlüsselwörter import und export, oder der JSX-Syntax). Es erfordert eine ziemlich umständliche Einrichtung, und Facebook hat mit "Create-React-App" eine Option bereitgestellt, die das Starten einer React-Anwendung einfach macht.

Warum sich dann die Mühe machen? Die Sache ist die, dass "Create-React-App" vieles von dem abstrahiert, was eine "React-App" überhaupt im Browser funktionieren lässt. Es gibt eine Reihe von Gründen warum man vielleicht eine eigene Implementierung machen will, oder zu-mindestens verstehen will welche Komponente im Prozess für was eigentlich zuständig ist.

Bestandteile einer typischen JavaScript Build Werkzeugkette

Node.js Logo

Typischerweise besteht eine JavaScript Build Werkzeugkette aus:

  • Einem Paket Manager wie Yarn oder npm, der einem Zugriff auf ein breites Ökosystem von Drittbibliotheken zur Verfügung stellt die man einfach installieren oder aktualisieren kann.
  • Einem Bundler wie webpack oder Parcel, der es einem erlaubt, modularen Code zu schreiben und ihn in kleine Pakete (Bundles) zu packen, unter anderem um die Ladezeit zu optimieren.
  • Einem Compiler/Transpiler wie Babel erlaubt es einem, Modernen JavaScript Code zu schreiben und ihn in Code umzuwandeln ("polyfill"en), den auch ältere Browser verstehen können.


Setup

Erstelle ein neues Verzeichnis für die React-Anwendung und öffne diesen Ordner in einem Terminal.

Diesen Ordner markieren wir als den Root-Pfad für eine neue Node-Anwendung mit dem Befehl npm init.

  • Falls man keine aktuelle Version der Node/NPM-SDK auf seinem System installiert hat, empfehle ich dringend nvm (Es ist wie sdkman, aber für node/npm - Ein Tool zum installieren/managen von SDKs mithilfe einer einfach Kommandozeilenumgebung).


Nun erstellt man im Projektordner folgende Struktur:

.
+-- public
  +-- index.html
+-- src

Unser public-Verzeichnis verwaltet alle statischen Assets und beherbergt vor allem unsere index.html-Datei, die als Einstiegspunkt unserer Anwendung für den Browser dient. Sie sieht wie folgt aus:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8" />
 5     <!--
 6         The X-UA-Compatible meta tag allows web authors to choose what version of Internet Explorer the page should be rendered as.
 7         According to Microsoft, when using the X-UA-Compatible tag, it should be as high as possible in your document head.
 8 
 9         "Edge" mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 9, this is equivalent to IE9 mode.
10 
11         See https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do
12     -->
13     <meta http-equiv="X-UA-Compatible" content="IE=edge">
14     <!--
15       Advised tag as described in https://material-ui.com/getting-started/usage/#responsive-meta-tag (and many other sources)
16       to ensure proper rendering and touch zooming for all devices:
17     -->
18     <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width"/>
19     <title>React Starter</title>
20 </head>
21 
22 <body>
23     <!-- This will serve as the top-level-entry-point/container in which our React-Elements will hook into. -->
24     <div id="root"></div>
25     <noscript>
26     You need to enable JavaScript to run this app.
27     </noscript>
28     <!-- This will load/execute our "Plain Vanilla Javascript"-File that has previously been bundled & transpiled to be able to run by an browser (built) by us. -->
29     <script src="../dist/bundle.js"></script>
30 </body>
31 </html>

Jetzt, wo wir unsere HTML-Seite eingerichtet haben, können wir anfangen, ernsthaft zu werden. Zunächst müssen wir sicherstellen, dass der Code, den wir schreiben, kompiliert werden kann.

Installieren der benötigten NPM-Pakete

npm (Node Package Manager) LOGO

Natürlich brauchen wir React, und ReactDOM um unsere Anwendung im Browser zu rendern (React kann auch nativ auf mobilen Plattformen wie iOS verwendet werden, wobei ReactNative anstelle von ReactDOM verwendet wird).

# Dependencies used by the actual code/app (--save)
npm install react react-dom \
    --save

# Dependencies used for development purposes (--save-dev)
# babel-preset-react will be responsible to transpile all react-syntax (including JSX)
# babel-preset-es2015 will be responsible for transpiling the transpiled code from the previous preset so it can work on es2015-compatible-browsers
npm install babel-core babel-preset-es2015 babel-preset-react babel-cli \
    webpack webpack-cli babel-loader style-loader css-loader \
    --save-dev

Babel

BabelJS Logo

Da wir zum Schreiben unserer Komponenten JSX verwenden werden, müssen wir außerdem einen Transpiler verwenden, um unseren React-Code in "Plain Vanilla"-Javascript für den Browser umzuwandeln. Moderne Javascript-Frameworks bewegen sich viel schneller als Web-Browser, und viele der Javascript-APIs die häufig in React-Projekten verwendet werden sind noch nicht Standard in Browsern. babel ist ein sehr beliebter und einfach-erweiterbarer Transpiler.

Da Babel sehr vielseitig ist müssen wir eine kleine Grundkonfiguration einrichten. Ohne Plugin versteht der babel-Transpiler auch nur so-gut-wie Plain-JavaScript Syntax. Damit babel auch neuere Versionen von JavaScript sowie den JSX-Syntax verstehen und transformieren kann, müssen wir entsprechende Plugins hinzufügen.

Die Babel-Konfiguration wird vorzugsweise in der Datei .babelrc im Stammverzeichnis des Node-Projekts vorgenommen. Sie kann wie folgt aussehen:

{
  "presets": [
    "react",
    "es2015"
  ]
}

Webpack

Webpack Logo

Bundling ist der Prozess, bei dem importierte Dateien verfolgt und zu einer einzigen Datei zusammengeführt werden: einem "Bündel". Dieses Bundle kann dann auf einer Webseite eingebunden werden, um eine ganze Anwendung auf einmal zu laden. Abhängigkeiten werden während der Kompilierung aufgelöst, wodurch die Laufzeitgröße reduziert wird.

Betrachte folgendes Beispiel:

Originaler Code Beispielhafte Darstellung des resultierenden Bundels
1 // app.js
2 import { add } from './math.js';
3 
4 console.log(add(16, 26)); // 42
1 // math.js
2 export function add(a, b) {
3   return a + b;
4 }
1 function add(a, b) {
2   return a + b;
3 }
4 
5 console.log(add(16, 26)); // 42

Webpack ist ein sehr mächtiges, hoch-modulares Werkzeug um solche Bündel zu erstellen. Loader kümmern sich um die Kompilierung bestimmter Dateitypen für webpack. babel-loader ist zum Beispiel ein loader für JavaScript-Dateien.

Erstelle eine neue Datei im Stammverzeichnis des Projekts mit dem Namen webpack.config.js. Diese Datei exportiert ein Objekt mit der Konfiguration von webpack.

// As this is run by NodeJS, it only supports CommonJS Syntax for importing
const path = require("path");
const webpack = require("webpack");

module.exports = {
  // tells Webpack where our application starts and where to start bundling our files.
  entry: "./src/index.js",
  // The following line lets webpack know we’re working in development mode 
  // — This saves us from having to add a mode flag when we run the development server.
  mode: "development",
  
  // The module object helps define how your exported javascript modules are transformed and which ones are included according to the given array of rules.
  module: {
    rules: [
      // Our first rule is all about transforming our ES6 and JSX syntax. 
      {
        // The test and exclude properties are conditions to match file against. In this case, it’ll match anything outside of the node_modules and bower_components directories.
        test: /\.(js|jsx)$/,
        exclude: /(node_modules|bower_components)/,
        // Since we’ll be transforming our .js and .jsx files as well, we’ll need to direct Webpack to use Babel. 
        // loader is a shorthand for the use property, when only one loader is being utilized.
        loader: "babel-loader",
        // Finally, we specify that we want to use the env preset in options.
        options: { presets: ['es2015', 'react'] }
      },
      // The next rule is for processing CSS. Since we’re not pre-or-post-processing our CSS, we just need to make sure to add style-loader and css-loader to the use property. css-loader requires style-loader in order to work. 
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      }
    ]
  },
  // The resolve property allows us to specify which extensions Webpack will resolve — this allows us to import modules without needing to add their extensions.
  resolve: { extensions: ["*", ".js", ".jsx"] },
  // The output property tells Webpack where to put our bundled code. The publicPath property specifies what directory the bundle should go in.
  output: {
    path: path.resolve(__dirname, "dist/"),
    // If this is set incorrectly, you’ll get 404’s as the server won’t be serving your assets from the correct location!
    publicPath: "/dist/",
    filename: "bundle.js"
  },
};

NPM-Skripte erstellen

Für die Zwecke der Einfachheit werden wir auch ein paar "NPM Skripte" zu unserer Node-Datei package.json hinzufügen wollen, um webpack über npm auszuführen. Fügen Sie diese beiden Zeilen im Abschnitt "scripts" hinzu:

"scripts": {
    "watch": "webpack --watch --colors --progress",
    "bundle": "webpack",

Diese Skripte können nun auf folgende Weise ausgeführt werden: npm run [name]

Beim ausführen von npm run bundle werden Sie wahrscheinlich einen Fehler wie "Entry module could not be found." von webpack kriegen, weil unserer in webpack angegebener entry-point nicht existiert. Also, fangen wir endlich an React-Code zu schreiben:

Beispiel-Code

// /src/index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App.js";

// ReactDOM.render is the function that tells React what to render and where to render it — In this case, we’re rendering a component called App (which we’ll create soon), and it’s being rendered at the DOM element with the ID "root".
ReactDOM.render(<App />, document.getElementById("root"));
// /src/App.js
// This file just holds a React component.

import React, { Component} from "react";
import "./App.css";

class App extends Component{
  render(){
    return(
      <div className="App">
        <h1> Hello, World! </h1>
      </div>
    );
  }
}

export default App;

Während wir noch hier sind, habe ich bereits erwähnt, dass Webpack auch CSS verarbeitet (und wir importieren es in unsere Komponente). Lassen Sie uns ein wirklich einfaches Stylsheet zum src-Verzeichnis hinzufügen:

// /src/App.css
// (kein statisches Asset im direkten Sinne - wird in die Javascript-Datei gebündelt und nur von dort aus erreichbar sein.)

.App {
  margin: 1rem;
  font-family: Arial, Helvetica, sans-serif;
}

Fertig

Nun können wir mithilfe von npm run bundle unseren Quellcode in eine einzelne, für den Browser verständliche und ausführbare Datei bündeln.

Jetzt sollten wir die index.html-Datei im Browser öffnen können und unsere Anwendung sollte erfolgreich geladen und angezeigt werden.