image
image

Nils Hartmann ist freiberuflicher Softwareentwickler, -architekt, Trainer und Coach. Er hat langjährige Erfahrung in der Entwicklung mit Java sowie JavaScript/TypeScript, ist Autor von Fachartikeln und unterstützt Teams mit Trainings und Coaching beim Einstieg in JavaScript und die Entwicklung von modernen Webanwendungen. Mehr unter: https://nilshartmann.net

image

Oliver Zeigermann ist Entwickler, Architekt, Berater und Coach aus Hamburg. Er hat über Jahrzehnte in vielen unterschiedlichen Sprachen und mit vielen Technologien und Ansätzen Software entwickelt. Er ist Autor zahlreicher Fachbücher im JavaScript und React-Bereich, sowie Experte für Machine und Deep Learning. Mehr unter: http://zeigermann.eu/

image

Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+:

www.dpunkt.plus

Nils Hartmann · Oliver Zeigermann

React

Grundlagen, fortgeschrittene Techniken
und Praxistipps – mit TypeScript und Redux

2., überarbeitete und erweiterte Auflage

image

Nils Hartmann, Oliver Zeigermann

Lektorat: René Schönfeldt

Bibliografische Information der Deutschen Nationalbibliothek

2., überarbeitete und erweiterte Auflage 2020

Hinweis:

image

Schreiben Sie uns:

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.

5 4 3 2 1 0

Inhaltsverzeichnis

Teil IEinstieg

1Einleitung

1.1Was ist React?

1.2Warum React?

1.3Beziehung zu anderen Technologien

1.4Vergleich mit anderen Webtechnologien

1.5Wie man dieses Buch benutzt

1.6Voraussetzungen für dieses Buch

1.7Änderungen gegenüber der ersten Auflage

1.8Website zum Buch

1.9Danksagungen

2Schnelldurchgang – React im Überblick

2.1Zusammengefasst: Unterschiede zwischen Hooks- und Klassen-API

2.2Ein React-Projekt beginnen mit Create React App

2.3Zusammenfassung

3Die Beispielanwendung: »Vote as a Service«

3.1Die Beispielanwendung installieren und ausführen

3.2Fachliches Modell

3.3Die Anwendung schrittweise entwickeln

3.4Zusammenfassung

Teil IIReact

4Eine React-Komponente

4.1Hands-on: eine Komponente

4.2React-Komponenten in der Übersicht

4.3Hooks

4.4Zustand verwalten mit useState

4.5Ereignisse und Event Handler

4.6JSX zur Beschreibung der UI

4.7Rückgabewerte von Komponenten

4.8Einhängen der Anwendung in den DOM

4.9Arbeiten mit CSS

4.10Zusammenfassung

5Arbeiten mit Komponentenhierarchien

5.1Hands-on: Hierarchien von Komponenten

5.2Kommunikation zwischen Komponenten

5.3Das »Render Properties«-Pattern

5.4Performance-Optimierung: Caching von Werten mit useMemo

5.5Performance-Optimierung: Rendern vom Komponenten unterdrücken

5.6Performance-Optimierung: Code-Splitting mit React.lazy und Suspense

5.7Der React Strict Mode

5.8Zusammenfassung

6Formulare mit React

6.1Hands-on: ein Editor für Umfragen

6.2Hintergrund: Databinding

6.3Controlled Components

6.4Uncontrolled Components

6.5Auf native DOM-Elemente zugreifen: das ref-Property

6.6Komplexen Zustand mit useReducer verwalten

6.7Zusammenfassung

7Arbeiten mit Seiteneffekten: asynchrone Serverzugriffe

7.1Hands-on: Serveranbindung

7.2Seiteneffekte mit useEffect

7.3Code wiederverwenden mit Custom Hooks

7.4Server-Requests mit useState und useReducer

7.5Ausblick: Daten laden mit Suspense

7.6Zusammenfassung

Teil IIIÜber React hinaus

8React-Anwendungen testen

8.1Hands-on: Testen mit Jest und React Testing Library

8.2Überblick: React-Anwendungen testen

8.3React-Test-Bibliotheken

8.4Snapshot Testing

8.5Zusammenfassung

9Der React Router

9.1Hands-on: der React Router im Schnelldurchgang

9.2Anpassungen an der Vote-Anwendung

9.3Links und Routen

9.4Navigation über die History

9.5Authentifizierung

9.6Die React Context API

9.7Lazy Loading mit dem React Router

9.8Testen

9.9Zusammenfassung

10Externes Statemanagement mit Redux

10.1Motivation

10.2Hands-on: eine Redux-Anwendung

10.3Redux in der Vote-Anwendung

10.4Arbeiten mit dem globalen Zustand

10.5Asynchrone Actions

10.6Alternative zu Hooks: die connect-Funktion

10.7Integration von Redux und React Router

10.8Testen von Redux-Anwendungen

10.9Exkurs: Codestruktur von großen React-Anwendungen

10.10Alternative zu Redux: MobX

10.11Zusammenfassung

11React-Anwendungen mit TypeScript

11.1Hands-on: eine React-Anwendung mit TypeScript

11.2TypeScript in React-Anwendungen

11.3React-Komponenten mit TypeScript

11.4Der React Router mit TypeScript

11.5Redux

11.6Zusammenfassung

12GraphQL mit dem Apollo Client für React

12.1Hands-on: ein GraphQL-Client

12.2GraphQL in der Vote-Anwendung

12.3Mutations

12.4Der Apollo Client Cache

12.5GraphQL für externes Statemanagement?

12.6Der Apollo React Client mit TypeScript

12.7Zusammenfassung

Anhang

AServerseitiges Rendern mit React

A.1Ein Beispiel

A.2Gründe für serverseitiges Rendern

A.3Serverseitiges Rendern im Überblick

A.4Herausforderungen

A.5Asynchrones Datenladen mit Redux und dem React Router

BKomponenten als Klassen

B.1React-Komponenten als ES6-Klasse

B.2Methoden-Binding für Event Handler

B.3Zugriff auf native DOM-Elemente

B.4Arbeiten mit Seiteneffekten

B.5Beispiel: Error Boundaries

B.6Klassenkomponenten mit TypeScript

CEinführung in ES.Next

C.1Einleitung

C.2Block-Scope

C.3Template Strings

C.4Destructuring

C.5Klassen

C.6Vererbung

C.7Erweiterte Objekt-Literale

C.8Module, Exporte und Importe

C.9Arrow-Funktionen

C.10Default- und Rest Parameter

C.11Spread-Operator für Arrays

C.12Object.assign und Spread-Operator bei Objekten

C.13Promises

C.14async/await

C.15Generatorfunktionen

C.16Die fetch-API

DEinführung in TypeScript

D.1Motivation

D.2Die Sprache TypeScript

D.3Grundlagen des TypeScript-Typsystems

D.4Externe Typbeschreibungen

EÜbersicht GraphQL

E.1Abfragen

E.2Das Schema: Beschreibung der API

Index

Teil I

Einstieg

1Einleitung

1.1Was ist React?

React1 ist eine Open-Source-JavaScript-Bibliothek, mit der du Webanwendungen, sogenannte Single-Page-Anwendungen (kurz SPAs), erstellen kannst. Die Bibliothek wird von Facebook entwickelt und sowohl für facebook.com als auch für Instagram benutzt. Aber auch darüber hinaus ist React sehr weit verbreitet und wird zum Beispiel von Netflix, Airbnb, Twitter oder der Online-Ausgabe des Wall Street Journals verwendet. Da React kaum Bedingungen an seine Umgebung stellt, ist es sehr flexibel einsetzbar. So gibt es auch Webseiten, die React nur für einige interaktive Teile ihres Angebots verwenden.

Single-Page-Anwendungen

Single-Page-Anwendungen (SPAs) zeichnen sich dadurch aus, dass sie vollständig auf dem Client, also im Browser, laufen. Sämtliche Interaktionen werden auf dem Client bearbeitet und die Darstellung der Seite wird mittels JavaScript erzeugt bzw. aktualisiert, um eine möglichst flüssige Darstellung zu erreichen. Mit dem Server werden JavaScript-Code, statische Assets (Bilder, Fonts etc.) und Daten ausgetauscht, aber kein HTML-Code. Zur Entwicklung von Single-Page-Anwendungen haben sich spezialisierte Frameworks und Bibliotheken (in erster Linie React, Angular, Vue oder Web Components) herausgebildet, die von der zugrunde liegenden DOM-API abstrahieren und die Entwicklung dieser Anwendungen vereinfachen.

Im Gegensatz zu SPAs findet bei serverseitig gerenderten Websites und Anwendungen (auch »klassische Webanwendungen« genannt) bei Interaktionen ein Server-Roundtrip statt, bei dem fertiger HTML-Code zurückgeliefert wird. Aus diesem Grund eignet sich dieser Ansatz nur für zumeist statische Websites, auch wenn diese mit JavaScript an einzelnen Stellen um interaktive Features erweitert werden können.

Den Kern von React bilden Komponenten und ihre Komposition zu einer Anwendung. Durch eine solche Komposition wird bestimmt, was dargestellt werden soll oder – aus einer anderen Perspektive – wie man den Zustand einer Anwendung in ihre Darstellung transformiert. Beispiele für den Zustand einer Anwendung können fachliche Dinge sein, wie die Anzahl ungelesener Nachrichten, ein Blogpost, der gerade in der Anwendung bearbeitet wird, oder der zurzeit angemeldete User. Aber auch technische Dinge, wie die Informationen, welches Menü gerade aufgeklappt oder welcher Eintrag in einer Combobox ausgewählt ist, sind Zustand der Anwendung.

Der Kern von React ist übrigens losgelöst vom Web: React kann in unterschiedlichen Szenarien funktionieren, so auch in nativen Anwendungen (zum Beispiel iOS oder Android).

In diesem Buch werden wir uns aber auf die Webentwicklung beschränken und daher auch davon ausgehen, dass du eine Webanwendung mit React bauen willst. Eine solche Anwendung wird früher oder später im DOM des Browsers – der Objektrepräsentation der dargestellten Elemente – gerendert werden. Dazu gibt es zwei Möglichkeiten. In der Regel wird die Anwendung auf Clientseite, also im Browser, gerendert. Du kannst deine Anwendung aber zusätzlich auf dem Server rendern lassen, sofern du dort eine JavaScript-Engine laufen lässt. Dann wird auf dem Server fertiger HTML-Code erzeugt, der zum Browser geschickt wird und dort vom Browser nur noch in den DOM umgewandelt und angezeigt werden muss. Von da an werden alle Updates im Browser gerendert. Das ist sehr praktisch zum Beispiel für eine schnelle erste Anzeige der Anwendung.

1.1.1Komponenten

React-Anwendungen werden in Komponenten aufgeteilt. Eine Komponente enthält alles Notwendige, um sich darzustellen. Dabei trennt React nicht zwischen Template und Logik; sowohl UI und Logik sind in der Komponente enthalten. Als Ersatz für das Template wird in React der UI-Code direkt in den JavaScript-Code einer Komponente geschrieben. Das geschieht mit der React-eigenen Spracherweiterung JSX, die es ermöglicht, HTML-artigen Code in JavaScript einzubinden.

Ohne an dieser Stelle schon in die Details zu gehen, könnte eine einfache Komponente, die in React als Funktion implementiert werden kann, wie folgt aussehen:

import React from "react";

export default function HelloMessage() {

return <h1>Hello, World</h1>;

}

Wenn diese Komponente in deiner Anwendung verwendet wird, sorgt React dafür, dass ein h1-Element in den DOM eingebaut wird, das den String »Hello, World« beinhaltet.

Deklarative Komponenten

»UI as a Function«

Du siehst an dieser Stelle ein weiteres, wichtiges Konzept von React: Komponenten werden ausschließlich deklarativ beschrieben. Eine Komponente gibt demnach immer nur genau die UI zurück, die dargestellt werden soll. Man spricht daher von »UI as a Function« in der React-Entwicklung, da – genau wie bei einer mathematischen Funktion – zu demselben Eingabeparameter (React: Zustand) immer derselbe Wert (React: UI) zurückkommt.

Zur Laufzeit kümmert sich React dann darum, dass auch der DOM im Browser entsprechend angepasst wird – und zwar unabhängig davon, wie der DOM zuvor aussah. Die einzelnen Übergänge von einer UI zur nächsten, also das jeweilige Aktualisieren des DOM im Brower, übernimmt React für dich und geht dabei sehr effizient und optimiert vor. Funktionen zum Erzeugen oder Löschen von Elementen (wie beispielsweise createElement oder createAttribute aus der DOM-API) brauchst du in React nicht.

Durch die deklarative Programmierung entfällt eine Menge Komplexität und Fehleranfälligkeit, die aus anderen Ansätzen bekannt sind, da eine wesentliche Fehlerquelle, die diversen Übergänge innerhalb einer Anwendung, nicht implementiert werden müssen. Auch das Testen von Komponenten wird dadurch sehr einfach. In deinem Test übergibst du deiner Komponente ihre Parameter und prüfst hinterher, dass die richtige UI zurückgeliefert wird – genau wie bei einer »normalen« Funktion, nur dass du UI-Elemente überprüfst und keine numerischen oder anderen Werte.

Eigenschaften einer Komponente

Im Folgenden sind die Eigenschaften einer Komponente zusammengefasst:

1.2Warum React?

In diesem Abschnitt möchten wir dir in aller Kürze Gründe nennen, warum man sich aus unserer Sicht mit React beschäftigen sollte und warum wir glauben, dass React eine sehr gute Bibliothek ist.

1.3Beziehung zu anderen Technologien

React hilft dir, Anwendungen für das Web zu bauen. Dabei ist React selten ganz allein im Einsatz. Insbesondere brauchst du für eine komplette Anwendung zumindest noch:

In größeren Anwendungen kommen meistens noch hinzu:

Die dazu passenden Techniken wollen wir nun kurz beleuchten.

1.3.1ES.Next-JavaScript und Babel

Wie du gesehen hast, brauchen wir zwingend einen Compiler, wenn wir JSX nutzen wollen, denn kein Browser unterstützt den JSX-Code nativ und wird es vermutlich auch nie tun. Zum Übersetzen von JSX ist Babel3 das empfohlene Werkzeug. Babel ist in der Lage, neben JSX die jeweils aktuellen und vielfach auch die kommenden JavaScript-Sprachfeatures, als ES.Next bezeichnet, nach ES5 zurückzuübersetzen, bis diese von allen Browsern unterstützt werden, für die du deine Anwendung zur Verfügung stellen willst.

ES5, ES6, ES.next, ... Historie der JavaScript-Sprachversionen

Wir beziehen uns in diesem Buch auf unterschiedliche Versionen von JavaScript. Unterschiedliche Begriffe können dabei leicht zu Verwirrung führen.

Zuerst zum Unterschied zwischen ECMAScript und JavaScript: ECMAScript ist die Spezifikation der Sprache, die von der Organisation Ecma International veröffentlicht wird. JavaScript ist die Implementierung dieser Spezifikation. In der Praxis spielt dieser Unterschied kaum eine Rolle, und so werden – wenn es um die Benennung einer Version geht – »JavaScript« und »ECMAScript« häufig synonym verwendet.

Von der Spezifikation der Sprache gibt es unterschiedliche Versionen. Bis Juni 2015 war ECMAScript 5 (kurz: ES5) die aktuellste Version, die zu dem Zeitpunkt auch von praktisch allen Browsern unterstützt wurde. Das ist auch der Grund, warum diese Version häufig noch als Zielversion beim Kompilieren verwendet wird (der Internet Explorer 11 zum Beispiel unterstützt weiterhin fast keine neueren JavaScript-Features).

Im Juni 2015 wurde dann der Nachfolger von ES5 veröffentlicht, der häufig als ES6 bezeichnet wird, offiziell aber ECMAScript 2015 heißt. Die Begriffe ECMAScript 6, ES6 und ECMAScript 2015 beziehen sich auf dieselbe Sprachversion. Mit dieser Version gab es sehr viele neue Sprachfeatures (wie Modulsystem, Klassen, Promises, Block Scoping mit let und const, Arrow-Funktionen etc.), sodass man dieses JavaScript auch als »modernes JavaScript« bezeichnet. Die Lern- und Adaptionskurve für dieses Release war und ist dementsprechend hoch.

Aus diesem Grund wird seit 2015 regelmäßig einmal pro Jahr eine neue Sprachversion veröffentlicht (ES5 ist bereits 2009 erschienen), die dafür weniger Features enthält. Diese Versionen werden nach dem Jahr ihres Erscheinens benannt, häufig aber auch noch als ES7, ES8 etc. bezeichnet.

Dazu kommt noch der Begriff ES.Next. Dieser bezeichnet die jeweils kommende, noch unveröffentlichte Version (in Babel kannst du beispielsweise einstellen, dass du ES.Next-Features in deinem Code verwenden und kompilieren möchtest).

Die von uns verwendeten neuen Konzepte ab ES6 haben wir zusammengefasst im Anhang C erläutert. Im React-Umfeld ist es gängig, neue und teilweise auch unveröffentlichte Sprachfeatures recht schnell einzusetzen, was dank Babel auch kein großes Problem ist.

1.3.2Webpack und Browserify

Modul-Loader

Wir strukturieren unsere Anwendung mit ES6-Modulen. Diese und ES6-Imports brauchen aber einen Modul-Loader (auch Bundler genannt), der Abhängigkeiten auflöst, da der Browsersupport für ES6-Imports noch nicht ausreichend ist. Mit Webpack4 und Browserify5 stehen uns hier zwei weitverbreitete Werkzeuge zur Verfügung. Beide lösen ES6-Importe auf und erzeugen je nach Konfiguration eine oder mehrere Ausgabedateien mit allen benötigten Abhängigkeiten. Webpack ist weit verbreitet und kommt auch bei Projekten zum Einsatz, die mit dem offiziellen React-Tool Create React App angelegt wurden.

Code-Splitting

Webpack unterstützt zudem Code-Splitting, das bedeutet, es kann deinen Code im Build in mehrere kleinere Ausgabedateien zerteilen, sodass der Browser initial nicht deine ganze Anwendung laden und interpretieren muss, sondern nur das, was zu einem Zeitpunkt wirklich benötigt wird. Code-Splitting wird auch von React unterstützt; mehr dazu findest du in Kapitel 5.6.

1.3.3TypeScript und Flow

Typensystem für JavaScript

Mit TypeScript6 hat Microsoft eine getypte Erweiterung von JavaScript geschaffen. Du kannst damit für jeden Parameter, jedes Property und jede Variable einen Typ angeben, außerdem kannst du die Struktur von Objekten mit Interfaces beschreiben. Solche Typannotationen haben viele Vorteile. Neben der besseren Lesbarkeit kann dich auch die IDE besser unterstützen. Durch Typannotationen wird auch in der JavaScript-Welt verlässliches Refactoring, Codeanalyse und Code-Completion möglich.

Gerade für größere Projekte, die über einen längeren Zeitraum laufen, halten wir einen Type-Checker für unumgänglich.

TypeScript-Compiler

Microsoft liefert auch gleich einen Compiler mit, der diese Typannotationen checkt und in ES5-Code (oder wahlweise sogar ES3) zurückübersetzt. Der übersetzte Code bleibt dabei lesbar. Da dieser Compiler ebenfalls JSX unterstützt, kannst du den TypeScript-Compiler auch als Alternative zu Babel verwenden.

Man kann diesen Stil der Typannotationen aber auch ohne den TypeScript-Compiler verwenden. Babel ist in der Lage, diese Annotationen herauszufiltern oder per Plug-in auch in der Ausgabe als Kommentar beizubehalten. Als Checker dient dann z.B. die IDE (WebStorm7 und Visual Studio Code8 haben einen sehr guten Support dafür) oder andere Kommandozeilen-Werkzeuge. In Kapitel 11 zeigen wir, wie du TypeScript in deiner React-Anwendung einsetzen kannst.

Ein weiteres Beispiel eines solchen Werkzeugs ist Flow9, das ebenfalls von Facebook entwickelt wird. Flow übersetzt das annotierte JavaScript nicht – das macht ja wie erwähnt bereits Babel –, sondern führt lediglich eine Überprüfung der Typen durch.

Sourcecode formatieren mit Prettier

Prettier10 ist ein Tool zum Formatieren von JavaScript-, TypeScript- und anderem Sourcecode, das in der React-Community eine hohe Verbreitung erfahren hat. Es gibt dafür Integrationen in zahlreiche IDEs und andere Tools. Die Idee hinter Prettier ist, dass unabhängig davon, wer mit welchem Tool den Sourcecode editiert, dieser immer gleich formatiert ist und somit zum Beispiel »überflüssige« Diffs durch unterschiedliche Formatierungen in der Versionsverwaltung vermieden werden.

Auch wenn Prettier nicht dazu gedacht ist, Fehler im Code zu finden, gibt es doch manchmal einen Hinweis darauf, dass sich Syntaxfehler eingeschlichen haben. Wenn der Code beim Speichern nicht automatisch formatiert wird, ist die Wahrscheinlichkeit hoch, dass sich irgendwo ein Syntaxfehler (fehlende Klammer o.Ä.) eingeschlichen hat.

1.3.4Router

URLs auf Komponenten abbilden

Auch in Single-Page-Anwendungen sollte das Navigieren über die URL des Browsers sowie des Back-Buttons funktionieren. Das Konzept dazu heißt Router: Dieser setzt einerseits die URL in der Navigationszeile des Browsers, sobald ein anderer Anwendungsteils aufgerufen wird. Andererseits kann der Router die zur URL passenden Komponenten ermitteln und rendern lassen.

Der React Router11 ist nur eine von vielen Router-Implementierungen, die mit React benutzt werden können. Allerdings hat er sich als De-facto-Standard etabliert. Daher werden wir dem React Router auch das komplette Kapitel 9 in unserem Buch widmen.

1.3.5Flux

Architekturmodell für React-Anwendungen

Flux12 ist ein von Facebook entwickeltes Architekturmodell, das beschreibt, wie mit React große Anwendungen gebaut werden können. Es definiert dazu ein Anwendungsmodell, bei dem Daten immer nur in eine Richtung durch die Anwendung fließen und dabei einen Kreislauf beschreiben. Das Modell ist weder auf React beschränkt noch ist es Bestandteil von React. Es gibt eine ganze Reihe von Frameworks, die die Flux-Architekturidee ausimplementieren. Die prominenteste Implementierung, die zumindest stark von dieser Idee inspiriert ist, ist Redux (siehe folgenden Abschnitt).

1.3.6Redux

Redux13 ist ein Werkzeug zum »externen Statemanagement«, mit dem du den Zustand deiner Anwendung verwalten kannst, auch wenn diese sehr groß wird. Es ist inspiriert von der Flux-Architektur und bringt eine Reihe von Architekturvorgaben mit. So wird der Zustand der Anwendung an einer einzigen zentralen Stelle gehalten und die Verarbeitung (Logik) geschieht durch pure Funktionen – sogenannte Reducer. Redux stellen wir dir in Kapitel 10 vor.

1.3.7Create React App

Das Aufsetzen eines neuen React-Projekts ist aufwendig, da eine ganze Reihe von Tools, insbesondere für den Build, notwendig ist. Das Konfigurieren und Pflegen des Tool-Stacks mit allen Abhängigkeiten kann einen nicht unerheblichen Aufwand auch während der Projektlaufzeit darstellen.

Um dieses Problem zu umgehen, gibt es das Kommandozeilentool Create React App14, mit dem du ein neues Projekt anlegen kannst. In diesem Projekt sind alle wichtigen Abhängigkeiten und das Tooling bereits eingetragen und vorkonfiguriert, sodass du sofort mit der Entwicklung beginnen kannst. Die Konfigurationen der verwendeten Tools (zum Beispiel für den Produktionsbuild), die dann für dein Projekt eingesetzt werden, entsprechen den React-Best-Practices und werden ständig erweitert und verbessert. Du kannst die Versionen der Konfiguration jederzeit in deinem Projekt aktualisieren, um die neuesten Features zu bekommen.

Das Tool Create React App stellen wir dir in Abschnitt 2.2 vor.

1.3.8React Developer Tools

Entwickertools für Chrome und Firefox

Für die Entwicklung von React-Anwendungen stehen die React Developer Tools zur Verfügung15. Dabei handelt es sich um eine Erweiterung für die Entwicklertools des Chrome- und Firefox-Browsers.

Die React Developer Tools zeigen in einem eigenen Tab die React-Komponenten einer Webseite sehr übersichtlich mitsamt ihren Properties und des aktuellen Zustands an. Die aktuellen Werte lassen sich darüber ebenfalls verändern, sodass du schnell ausprobieren kannst, wie sich deine Komponente mit anderen Properties verhalten würde.

image

Abb. 1–1Die React Developer Tools

1.4Vergleich mit anderen Webtechnologien

Neben React gibt es eine ganze Reihe weiterer Webtechnologien. Manche dieser Techniken sind ergänzend und andere wiederum für denselben Einsatzzweck gedacht und stellen damit eine Konkurrenz dar. Ein Vergleich kann für eine Einordnung spannend sein und dir beim Einstieg helfen, wenn du bereits Erfahrungen mit einer der folgenden Techniken hast.

1.4.1Web Components

Web Components

Web Components sind der Standard für eine ganze Reihe von Techniken sein16. Jede dieser Techniken kann man in Kombination mit den anderen oder für sich allein verwenden.

Custom Elements17 erlauben die Definition von eigenen HTML-Tags inklusive lokalem CSS und JavaScript. Du kannst also sowohl Aussehen als auch Verhalten für ein solches neues HTML-Tag definieren.

Shadow DOM

Über das sogenannte Shadow DOM18, in dem sich die Komponente darstellt, wird die Lokalität der Komponente realisiert.

HTML Templates19 lassen dich HTML in die Seite einbinden, ohne dass es unmittelbar auf der Seite dargestellt wird. Dies kann nützlich sein, um das Template später durch ein Skript mit Werten zu versehen und im Browser-DOM darzustellen. Obwohl diese Erweiterung als Teil von Web Components begonnen hat, wird sie nun als Teil der HTML-Spezifikation weiterentwickelt.

Die Programmierung von Web Components erfolgt imperativ und mit Listenern. Die Bibliothek Lit Elements20 stellt für Web Components ein deklaratives Programmiermodell zur Verfügung, das vom Konzept an React erinnert.

Sind Web Components komplementär oder Konkurrenz zu React?

Verwendung von Web Components in React-Komponenten

Web Components können wie jedes andere HTML-Element in einer React-Komponente genutzt werden. Diese Möglichkeit war eine bewusste Entscheidung der React-Entwickler. Hier sperrt man sich also nicht gegen Web Components, auch wenn es bei der Integration einige technische Schwierigkeiten gibt21.

Andere wiederum sehen in React eher eine Konkurrenz zu Web Components, sind aber mit React nicht zufrieden, weil es kein Standard ist. Laut der Aussage eines React-Kern-Entwicklers wird sich React nicht an Web Components annähern, allerdings auch nicht den Gebrauch zusammen mit React ausschließen, sondern ihn so weit wie möglich unterstützen22.

1.4.2Angular

Der Hype »vor React«

Angular kommt in zwei unterschiedlichen Versionen daher, die mehr oder weniger unterschiedlich und inkompatibel sind. Angular 123 (»AngularJS«) gibt es schon sehr lange und man kann es ohne Wenn und Aber den »Hype vor React« nennen. Angular in der Version 2 hat mit einer ganzen Reihe von Konzepten aus Angular 1 gebrochen. Die Versionen ab Angular 2 werden deswegen auch »Angular« genannt (im Gegensatz zu »AngularJS«, was sich auf Version 1 bezieht).

Sowohl AngularJS als auch Angular sind jeweils ein komplettes Framework, inklusive Router und klaren Vorstellungen von einer Architektur und der Art und Weise, wie getestet wird. So gibt es neben Komponenten zum Beispiel ein Modulkonzept, Services und Dependency Injection. Angular ist mit TypeScript entwickelt und auch Angular-Anwendungen werden darin geschrieben.

1.4.3Vue

Vue24 ist ebenfalls ein komponentenbasiertes JavaScript-Framework zur Entwicklung von Single-Page-Anwendungen. Im Gegensatz zu React kommen hier viele Bausteine mit, etwa ein Router und eine offiziell unterstützte Redux-Version für das Zustandsmanagement.

Vue verwendet genau wie Angular eine Template-Sprache, hat aber eine schlankere API und macht weniger Vorgaben, wie die Anwendung strukturiert sein soll. Das Framework wurde 2014 veröffentlicht, wird von einer Open-Source-Community entwickelt und hat sehr schnell eine große Verbreitung gefunden. Die Version 3 von Vue wird genau wie Angular in TypeScript entwickelt.

1.4.4React Native

Native Anwendungen mit React Native

React Native bietet eine Möglichkeit, mit React native Komponenten nicht nur für das Web, sondern auch für andere Systeme (unter anderem Android und iOS) zu entwickeln. Dabei wird eine andere Version des virtuellen DOM verwendet, die eine React-Komponente nicht für den DOM aufbereitet, sondern auf native Komponenten des Betriebssystems abbildet. Als JavaScript-Engine kommt sowohl bei Android als auch bei iOS Webkits JavaScript-Engine JavaScriptCore25 zum Einsatz.

1.5Wie man dieses Buch benutzt

Die in diesem Buch behandelten Themen sind komplex und umfangreich, zudem befinden sie sich in vielen Teilen im Fluss. Alle Themen auf dem neuesten Stand in einem Buch zu behandeln, ist daher nicht möglich. Stattdessen nehmen wir dich als Leser an die Hand und führen dich an die zentralen Themen der React-Welt heran. Für einige Details und weiterführende Informationen verweisen wir mithilfe von Links auf die aktuellsten Quellen im Internet.

Die Teile des Buchs

Das Buch gliedert sich in drei Teile.

Hands-on-Abschnitte

Jedes Kapitel in Teil II und III beginnt mit einem Hands-on-Abschnitt. In diesem werden anhand eines praktischen Beispiels die wichtigsten Konzepte des Kapitels erläutert. In den weiteren Teilen des Kapitels wird dann je nach Schwerpunkt des Kapitels die Anwendung weiterentwickelt und/oder auf weitere Details eingegangen.

Auch wenn du die in den Hands-on-Teilen beschriebenen Schritte nicht selber nachprogrammierst, kannst du damit einen praktischen Überblick über das vorgestellte Thema bekommen. Daher haben wir in den Teilen auch relativ viel Code abgedruckt, damit du zum Nachvollziehen nicht vor dem Computer sitzen musst.

Die Kapitel des Buchs bauen aufeinander auf. Ab Kapitel 4 verwenden wir durchgehend unsere Beispielanwendung, um die Konzepte von React zu demonstrieren. Insbesondere im dritten Teil sind die vorgestellten Technologien und Bibliotheken teilweise so komplex, dass wir sie am Anfang des Kapitels im Hands-on-Teil an einem kleinen, separaten Beispiel zeigen. Im Laufe des Kapitels beschreiben wir dann in Ausschnitten, wie sich die jeweilige Technologie auf unsere Anwendung auswirkt.

1.6Voraussetzungen für dieses Buch

ES5-Kenntnisse notwendig

Wir verwenden in diesem Buch konsequent die JavaScript-Versionen ECMAScript 2015 und neuer (ES.Next). Es genügt aber, wenn du mit der vorangegangenen Version ES5 vertraut bist. Die wichtigsten von uns verwendeten Neuerungen der Sprache haben wir im Anhang zusammengestellt, sodass du dort bei Bedarf nachschlagen kannst.

HTML und DOM

Neben ES5 solltest du außerdem HTML und das Document Object Model (DOM) kennen.

npm

Wenn du die Beispiele ausprobieren möchtest, muss auf deinem Rechner der Node Package Manager npm installiert sein. Mit npm werden wir die Module (Frameworks und Bibliotheken) für unsere Anwendung installieren und die Anwendung auch starten. Achtung: Die Beispiele sind mit npm in der Version 6.9.x getestet!

Node.js

Für den serverseitigen Beispielcode verwenden wir Node.js. Wenn du diese Teile ausprobieren möchtest, brauchst du eine Node.js-Installation auf deinem Rechner. (Wir haben mit Version 10.16.x getestet.)

1.7Änderungen gegenüber der ersten Auflage

Die zweite Auflage wurde komplett überarbeitet und stellt jetzt die Hooks-API in den Vordergrund. Wir zeigen die wichtigsten React Hooks sowie die Hooks-API von React Router, Redux und GraphQL.

Neu hinzugekommen sind außerdem Beschreibungen diverser React-APIs, wie Suspense, Caching oder Code-Splitting, Tests mit der React Testing Library und das Tool Create React App. Außerdem betrachten wir die Entwicklung von React-Anwendungen mit TypeScript. Als Grundlage dafür gibt es im Anhang eine Einführung in die Sprache TypeScript.

1.8Website zum Buch

Wir haben zu diesem Buch eine Website eingerichtet, über die du unter anderem zu unserem GitHub-Repository mit dem Beispielcode findest. Auf der Seite werden wir aber auch Korrekturen und Ergänzungen zum Buch und zu den Beispielen veröffentlichen, insbesondere auch zu Neuerungen in React. Die Adresse der Seite lautet:

https://reactbuch.de

Anregungen, Kommentare und Fragen nehmen wir jederzeit gerne entgegen. Du kannst uns erreichen unter der E-Mail-Adresse:

reactbuch@nilshartmann.net

oder über Twitter:

Nils Hartmann @nilshartmann

Oliver Zeigermann @DJCordhose

Alternativ kannst du uns auch im GitHub-Repository der Beispielanwendung gerne einen Issue einstellen (https://github.com/react-buch/vote-example-v2/issues).

1.9Danksagungen

Bei der Erstellung dieses Buchs haben uns eine ganze Reihe von Menschen geholfen, denen wir ganz herzlich danken wollen!

Unser Dank gilt dabei auch denjenigen, die das Buch schon vor der Fertigstellung gelesen und kommentiert haben und die auch für diese zweite Auflage sehr gutes Feedback gegeben haben.

Darüber hinaus möchten wir uns ganz herzlich beim Team vom dpunkt.verlag und allen an der Produktion Beteiligten bedanken, die uns nach Kräften geholfen und mit Rat und Tat zur Seite gestanden haben.

2Schnelldurchgang – React im Überblick

Bevor wir in die Details von React gehen, möchten wir dir in diesem Kapitel die wichtigsten Features von React im Schnelldurchgang an einem sehr einfachen Beispiel zeigen. Das Beispiel kannst du auf der Plattform CodeSandbox, die Online-Editoren für JavaScript anbietet, nachvollziehen, ohne dass du dafür etwas bei dir lokal auf deinem Computer installieren musst. (CodeSandbox selbst ist übrigens auch mit React gebaut.)

Vorbereitung

Um das Beispiel zu entwickeln, kannst du in CodeSandbox ein neues React-Projekt anlegen. Dazu öffnest du https://codesandbox.io/, klickst auf »Create Sandbox« und wählst dann unter »Popular Templates« »React« aus. Daraufhin wird ein Projekt angelegt, in dem die Abhängigkeiten auf die React-npm-Module bereits hinzugefügt sind und einige weitere Dateien angelegt sind.

Je nach Einstellung findest du auf der linken Seite einen Explorer mit allen Dateien des Projekts, in der Mitte einen Editor (der sich wie VS Code verwenden lässt!) und rechts die Darstellung deiner Anwendung in einem simulierten Browser. Sobald du den Code deiner Anwendung veränderst, wird die Anwendung übersetzt (z.B. JSX nach ES5) und die Darstellung im simulierten Browser automatisch aktualisiert.

Für diesen Schnelleinstieg wollen wir eine ganz einfache Hello-World-Anwendung bauen, die nur aus einer einzigen Komponente besteht. Komponenten sind das zentrale Element in React und wie wir später noch sehen werden, sind Anwendungen in React nichts weiter als eine Menge von Komponenten.

image

Abb. 2–1Der Online-Editor CodeSandbox mit Datei-Explorer, Editor und Vorschau der Anwendung

Die Komponente unserer Anwendung, Greeter, besteht aus einem Eingabefeld, in dem ein Gruß eingegeben werden kann. Der eingegebene Gruß darf eine bestimmte Länge nicht überschreiten. Die Anzahl der verbleibenden Zeichen steht unterhalb des Eingabefeldes. Außerdem gibt es einen Knopf, der den aktuellen Gruß ausgibt. Aktiv ist der Knopf allerdings nur, wenn der Gruß »gültig« ist, das bedeutet, er enthält mindestens ein Zeichen und die Länge ist kleiner oder gleich der erlaubten Maximallänge.

Beispiel: die Greeter-Komponente

Der erste Schritt unserer Anwendung sieht wie folgt aus, du kannst diesen Code so, wie er da steht, in die index.js-Datei deiner Sandbox einsetzen:

import React from "react";

export default function Greeter(props) {

const [greeting, setGreeting] = React.useState("");

function handleGreetClick() {

alert(`Hello, ${greeting}`);

}

const charsRemaining = props.maxLength - greeting.length;

const greetingInvalid = greeting.length === 0

|| charsRemaining < 0;

return (

<div>

Greeting:

<input value={greeting}

onChange={e => setGreeting(e.target.value)} />

<span>{charsRemaining}</span>

<button disabled={greetingInvalid}

onClick={handleGreetClick}>Greet

</button>

</div>

);

}

Sehen wir uns den Code der Komponente Schritt für Schritt an. Eine Komponente in React ist eine JavaScript-Funktion. In dieser Komponentenfunktion ist alles enthalten, was die Komponente benötigt, um sich darstellen zu können: sowohl die Logik als auch die UI.

Beschreibung der UI mit JSX

Die UI, die unsere Komponente darstellen soll, findest du im return-Statement der Komponente. Dort haben wir mit einer HTML-artigen Syntax die Elemente beschrieben, die zur Laufzeit im Browser dargestellt werden sollen. Dieser HTML-artige Code, JSX genannt, wird zur Build-Zeit von einem Compiler (Babel oder TypeScript) in gültiges JavaScript übersetzt. Für uns hat dieser Ansatz den Vorteil, dass wir keine Template-Sprache lernen und verwenden müssen (auch wenn dieses Vorgehen am Anfang sicherlich gewöhnungsbedürftig und vielleicht sogar abschreckend sein mag).

Variablen verwenden

Innerhalb des JSX-Codes können wir auf JavaScript-Variablen und -Funktionen zugreifen. Im Button, der den Gruß anzeigen soll, geben wir damit an, ob der Button aktiv oder inaktiv sein soll. Außerdem geben wir eine Callback-Funktion an, die ausgeführt werden soll, sobald auf den Button geklickt wird. Diese Eigenschaften eines Elementes werden in React Properties genannt. Sowohl disabled als auch onClick sind somit Properties des Button-Elements, genauso wie value und onChange Properties des input-Felds sind.

Properties

maxLengthpropsprops.maxLength