Webtechnologien Wintersemester 2024

React ⚛

Kurzfassung

  • JS-Bibliothek zur komponentenbasierten Entwicklung von User Interfaces
  • Open Source, Kernteam aus Facebook-Angestellten
    (mittlerweile viele davon bei Vercel)
  • primärer Anwendungszweck sind dynamische, datenlastige Anwendungen
  • e.g. Facebook, E-Mail-Client, Dashboard
  • häufig SPA, aber auch SSR-Support

Grundlagen

Wir bauen uns eine Hello-World-App.

  • React API
  • JSX
  • Custom Components
  • Styling
  • Forms
  • Arrays
  • erste Hooks

Setup

  • Obwohl wir im Frontend arbeiten, brauchen wir Node und npm
  • React DevTools für Chrome oder Firefox sind empfohlen

Installation einer neuen App

npm create vite@latest mein-react-projekt -- --template react

npm install    # Abhängigkeiten installieren
npm run dev    # Startet Entwicklungsserver
npm run build  # Baut fertige Anwendung
  • Vite bringt uns:
    • Dev Server
    • Fast Refresh
    • Compiler
    • Bundler
    • Code Quality
      • ESLint
      • Prettier
      • editorconfig
    • Styles
      • import css
      • import modules

Kernkonzepte

Kernkonzepte

  1. Deklarative Interfaces
  2. JSX
  3. Komponenten
  4. Props und State
  5. Virtual DOM und DOM-Diffing
  • Live-Editor auf https://react.new nutzen

Deklarative Interfaces

UI

  • Jede mögliche Darstellung wird initial beschrieben
  • keine imperativen Änderungen
  • Re-render the whole app on every update
  • data changing over time is the root of all evil
    • Wir können gut räumlich visuell denken (und in zielzuständen), aber wir können schlecht prozesse über zeit visualisieren
  • Reacts Design: keine Änderung über die Zeit zuzulassen sondern re-rendern der gesamten anwendung bei jedem update
  • re-render don’t muate / immutable interfaces -> änder deine daten, nicht die UI
  • state muss explizit und vollständig sein: nur so kann die UI re-rendered werden – in anderen frameworks implizit-lücken möglich

JSX

  • JavaScript XML
  • eigene Sprache, die verschachtelte Funktionsaufrufe in einer XML-artigen Struktur darstellt und JS-Ausdrücke enthalten kann
  • Seperation of Concerns – not Technologies
<main>
   <h1>Guten {new Date().getHours() < 12 ? 'Morgen' : 'Tag'}</h1>
   <article>
      {['Alice', 'Bob', 'Caesar'].map(name =>
         <h2 key={name}>Hallo {name}</h2>
      )}
   </article>
</main>
  • (React braucht JSX nicht, aber es vereinfacht die UI-Arbeit)
  • jede Template-Sprache, die versucht, Logik einzubetten, scheitert daran, niemals so ausdrucksstark zu sein wie eine echte Programmiersprache
  • JSX hat daher keine neue Template-Syntax, keine unspezifizierte komplexe string-interpolierte DSL, sondern einfach HTML mit JavaScript
  • Elemente, Expressions, Conditions
  • Die Zugänglichkeit von Templates mit der Ausdrucksstärke von JavaScript

  • UI zwangsläufig mit Geschäftslogik verbunden
  • JSX fördert starkes Coupling zwischen UI und Logik – aber das ist nicht schlecht, sondern Absicht
  • Coupling heißt im endeffekt: wenn ich etwas an meinem code ändern möchte, an wie vielen stellen / in wie vielen dateien muss ich das tun
  • MVC / template + controller + model trennt nach aufgaben, aber sie sind meist so eng verbunden, dass ich sie nur auf verschiedene dateien aufteile – kognitive mehrarbeit ohne vorteil
  • JSX verbindet Template, Logik und Styles
  • Das Gegenstück zur starken Kopplung in JSX sind Komponenten
    • Komponenten als lose-gekoppelte Einheit und grundlegender Baustein im Concerns zu trennen

Komponenten

  • Komplexe Interfaces können in kleine, wiederverwendbare Teile zerlegt werden
<div>
   <Header />
   <main>
      <Content />
   </main>
   <Footer />
   <PrivacyPrompt />
</div>
  • Komponenten sind gekapselt und verwalten ihren eigenen Zustand. Diese kann man dann komplexen UIs zusammensetzen
  • Für mich das erste Komponenten-Modell, das wirklich funktioniert
  • Komponenten sind super
  • In (guten) React-Projekten sind Leute fast sofort einsetzbar, weil die Arbeit auf Komponenten-Ebene stattfindet, das heißt die nötge Menge an Wissen für eine Änderung ist meist sehr gering bzw. in einer oder wenigen Komponenten
  • Komponenten keine Lösung an sich: Spaghetti-Code immer noch möglich, aber dann muss man halt
    • Komponenten zerlegen
    • Code in utilities auslagern
    • Data-Fetching über eigene Services abstrahieren

Props und State

  • Eltern geben Informationen an Kinder (Props)
  • Komponenten können private Daten haben (State)
  • Unidirektionaler Datenfluss / Status-Updates immer explizit (kein two-way data binding)
  • Daten fließen Top-Down, keine Event-System (neben DOM)
  • two-way-data-binding in anderen sprachen sieht einfach aus und wirkt gut in demos, aber man kommt schnell an den punkt, an dem nicht mehr nachvollziehbar ist, was passiert (ein wert ändert sich und man weiß nicht, welcher teil des codes dafür verantwortlich war)
  • react braucht anfänglich mehr code (z.B. listener für input field), aber man sieht, wer was macht – und so auch die kollegen. man braucht weniger kenntnis des konkreten codes

Virtual DOM und DOM-Diffing

  • Abgleich gegen virtuelles Abbild des DOMs, dann echte DOM-Operationen nur für Diff
  • Implementierungs-Detail / Performance-Hack um Re-Rendering schnell hinzubekommen, aber an sich konzeptionell nicht wichtig
  • bei jeder änderung nimmt react den aktuellen state, berechnet, wie alle Elemente für die UI aussehen sollte und gleicht diesen zustand dann mit dem aktuellen zustand ab, findet die unterschiede und generiert nur für diese unterschiede die notwendigen DOM-Operationen, die dann ausgeführt werden
  • reine implementierungs-notwendigkeit, um design philosophie performant umsetzen zu können
  • geht auch ohne, dann nur leider häufig langsam
  • Virtual DOM ist keine Magie – man könnte es per Hand womöglich schneller machen, aber es ist meist schnell genug

Hooks

State & Effects mit Hooks