Webtechnologien
Wintersemester 2024
React.js
♯
♫
React.js
<section id="react-" class="slide cover"><div><h2>React ⚛</h2> </div></section> <section class="slide" id="kurzfassung"><div><h2>Kurzfassung</h2> <ul> <li>JS-Bibliothek zur komponentenbasierten Entwicklung von User Interfaces</li> <li>Open Source, Kernteam aus Facebook-Angestellten <br /><small>(mittlerweile viele davon bei Vercel)</small></li> </ul> <footer> <ul> <li>primärer Anwendungszweck sind dynamische, datenlastige Anwendungen</li> <li>e.g. Facebook, E-Mail-Client, Dashboard</li> <li>häufig SPA, aber auch SSR-Support</li> </ul> </footer> </div></section> <section class="slide" id="grundlagen"><div><h2>Grundlagen</h2> <p><em>Wir bauen uns eine Hello-World-App.</em></p> <ul> <li>React API</li> <li>JSX</li> <li>Custom Components</li> <li>Styling</li> <li>Forms</li> <li>Arrays</li> <li>erste Hooks</li> </ul> </div></section> <section class="slide" id="setup"><div><h2>Setup</h2> <ul> <li>Obwohl wir im Frontend arbeiten, brauchen wir <a href="https://nodejs.org/">Node</a> und <a href="https://www.npmjs.com/">npm</a></li> <li>React DevTools für <a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en">Chrome</a> oder <a href="https://addons.mozilla.org/en-US/firefox/addon/react-devtools/">Firefox</a> sind empfohlen</li> </ul> <h3 id="installation-einer-neuen-app">Installation einer neuen App</h3> <ul> <li>Schnell zum Spielen: <a href="https://react.new/">react.new</a></li> <li>Lokales Projekt mit <a href="https://vite.dev/">Vite</a></li> </ul> <pre class="highlight language-sh" data-lang="sh"><code>npm create vite@latest mein-react-projekt <span class="nt">--</span> <span class="nt">--template</span> react npm <span class="nb">install</span> <span class="c"># Abhängigkeiten installieren</span> npm run dev <span class="c"># Startet Entwicklungsserver</span> npm run build <span class="c"># Baut fertige Anwendung</span> </code></pre> <footer> <ul> <li>Vite bringt uns: <ul> <li>Dev Server</li> <li>Fast Refresh</li> <li>Compiler</li> <li>Bundler</li> <li>Code Quality <ul> <li>ESLint</li> <li>Prettier</li> <li>editorconfig</li> </ul> </li> <li>Styles <ul> <li>import css</li> <li>import modules</li> </ul> </li> </ul> </li> </ul> </footer> </div></section> <section class="slide shout" id="kernkonzepte"><div><h2>Kernkonzepte</h2> </div></section> <section class="slide" id="kernkonzepte-1"><div><h2>Kernkonzepte</h2> <ol> <li>Deklarative Interfaces</li> <li>JSX</li> <li>Komponenten</li> <li>Props und State</li> <li>Virtual DOM und DOM-Diffing</li> </ol> <footer> <ul> <li>Live-Editor auf https://react.new nutzen</li> </ul> </footer> </div></section> <section class="slide" id="deklarative-interfaces"><div><h2>Deklarative Interfaces</h2> <p><img src="user-profile.jpg" alt="UI" class="right" /></p> <ul> <li>Jede mögliche Darstellung wird initial beschrieben</li> <li>keine imperativen Änderungen</li> <li><q>Re-render the whole app on every update</q></li> </ul> <footer> <ul> <li><q>data changing over time is the root of all evil</q> <ul> <li>Wir können gut räumlich visuell denken (und in zielzuständen), aber wir können schlecht prozesse über zeit visualisieren</li> </ul> </li> <li>Reacts Design: keine Änderung über die Zeit zuzulassen sondern re-rendern der gesamten anwendung bei jedem update</li> <li>re-render don’t muate / <q>immutable interfaces</q> -> änder deine daten, nicht die UI</li> <li>state muss explizit und vollständig sein: nur so kann die UI re-rendered werden – in anderen frameworks <q>implizit-lücken</q> möglich</li> </ul> </footer> </div></section> <section class="slide" id="jsx"><div><h2>JSX</h2> <ul> <li>JavaScript XML</li> <li>eigene Sprache, die verschachtelte Funktionsaufrufe in einer XML-artigen Struktur darstellt und JS-Ausdrücke enthalten kann</li> <li>Seperation of Concerns – not Technologies</li> </ul> <pre class="highlight language-js" data-lang="js"><code><span class="o"><</span><span class="nx">main</span><span class="o">></span> <span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="nx">Guten</span> <span class="p">{</span><span class="k">new</span> <span class="nc">Date</span><span class="p">().</span><span class="nf">getHours</span><span class="p">()</span> <span class="o"><</span> <span class="mi">12</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">Morgen</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">Tag</span><span class="dl">'</span><span class="p">}</span><span class="o"><</span><span class="sr">/h1</span><span class="err">> </span> <span class="o"><</span><span class="nx">article</span><span class="o">></span> <span class="p">{[</span><span class="dl">'</span><span class="s1">Alice</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Bob</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Caesar</span><span class="dl">'</span><span class="p">].</span><span class="nf">map</span><span class="p">(</span><span class="nx">name</span> <span class="o">=></span> <span class="o"><</span><span class="nx">h2</span> <span class="nx">key</span><span class="o">=</span><span class="p">{</span><span class="nx">name</span><span class="p">}</span><span class="o">></span><span class="nx">Hallo</span> <span class="p">{</span><span class="nx">name</span><span class="p">}</span><span class="o"><</span><span class="sr">/h2</span><span class="err">> </span> <span class="p">)}</span> <span class="o"><</span><span class="sr">/article</span><span class="err">> </span><span class="o"><</span><span class="sr">/main</span><span class="err">> </span></code></pre> <footer> <ul> <li>(React braucht JSX nicht, aber es vereinfacht die UI-Arbeit)</li> <li>jede Template-Sprache, die versucht, Logik einzubetten, scheitert daran, niemals so ausdrucksstark zu sein wie eine echte Programmiersprache</li> <li>JSX hat daher keine neue Template-Syntax, keine unspezifizierte komplexe string-interpolierte DSL, sondern einfach HTML mit JavaScript</li> <li>Elemente, Expressions, Conditions</li> <li> <p><q>Die Zugänglichkeit von Templates mit der Ausdrucksstärke von JavaScript</q></p> </li> <li>UI zwangsläufig mit Geschäftslogik verbunden</li> <li>JSX fördert starkes Coupling zwischen UI und Logik – aber das ist nicht schlecht, sondern Absicht</li> <li><q>Coupling</q> 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</li> <li>MVC / <q>template + controller + model</q> trennt nach aufgaben, aber sie sind meist so eng verbunden, dass ich sie nur auf verschiedene dateien aufteile – kognitive mehrarbeit ohne vorteil</li> <li>JSX verbindet Template, Logik und Styles</li> <li>Das Gegenstück zur starken Kopplung in JSX sind Komponenten <ul> <li>Komponenten als lose-gekoppelte Einheit und grundlegender Baustein im <q>Concerns</q> zu trennen</li> </ul> </li> </ul> </footer> </div></section> <section class="slide" id="komponenten"><div><h2>Komponenten</h2> <ul> <li>Komplexe Interfaces können in kleine, wiederverwendbare Teile zerlegt werden</li> </ul> <pre class="highlight language-js" data-lang="js"><code><span class="o"><</span><span class="nx">div</span><span class="o">></span> <span class="o"><</span><span class="nx">Header</span> <span class="o">/></span> <span class="o"><</span><span class="nx">main</span><span class="o">></span> <span class="o"><</span><span class="nx">Content</span> <span class="o">/></span> <span class="o"><</span><span class="sr">/main</span><span class="err">> </span> <span class="o"><</span><span class="nx">Footer</span> <span class="o">/></span> <span class="o"><</span><span class="nx">PrivacyPrompt</span> <span class="o">/></span> <span class="o"><</span><span class="sr">/div</span><span class="err">> </span></code></pre> <footer> <ul> <li>Komponenten sind gekapselt und verwalten ihren eigenen Zustand. Diese kann man dann komplexen UIs zusammensetzen</li> <li>Für mich das erste Komponenten-Modell, das wirklich funktioniert</li> <li>Komponenten sind super</li> <li>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</li> <li>Komponenten keine Lösung an sich: Spaghetti-Code immer noch möglich, aber dann muss man halt <ul> <li>Komponenten zerlegen</li> <li>Code in utilities auslagern</li> <li>Data-Fetching über eigene Services abstrahieren</li> </ul> </li> </ul> </footer> </div></section> <section class="slide" id="props-und-state"><div><h2>Props und State</h2> <ul> <li>Eltern geben Informationen an Kinder (Props)</li> <li>Komponenten können private Daten haben (State)</li> <li>Unidirektionaler Datenfluss / Status-Updates immer explizit (kein <q>two-way data binding</q>)</li> </ul> <footer> <ul> <li>Daten fließen Top-Down, keine Event-System (neben DOM)</li> <li><q>two-way-data-binding</q> 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)</li> <li>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</li> </ul> </footer> </div></section> <section class="slide" id="virtual-dom-und-dom-diffing"><div><h2>Virtual DOM und DOM-Diffing</h2> <ul> <li>Abgleich gegen virtuelles Abbild des DOMs, dann echte DOM-Operationen nur für Diff</li> <li>Implementierungs-Detail / Performance-Hack um Re-Rendering schnell hinzubekommen, aber an sich konzeptionell nicht wichtig</li> </ul> <footer> <ul> <li>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</li> <li>reine implementierungs-notwendigkeit, um design philosophie performant umsetzen zu können</li> <li>geht auch ohne, dann nur leider häufig langsam</li> <li>Virtual DOM ist keine Magie – man könnte es per Hand womöglich schneller machen, aber es ist meist schnell genug</li> </ul> </footer> </div></section> <section class="slide shout" id="hooks"><div><h2>Hooks</h2> </div></section> <section class="slide" id="state--effects-mit-hooks"><div><h2>State & Effects mit Hooks</h2> <ul> <li><a href="https://react.dev/reference/react/useState">State Hook</a> <code class="language-plaintext highlighter-rouge">useState</code></li> <li><a href="https://react.dev/reference/react/useEffect">Effect Hook</a> <code class="language-plaintext highlighter-rouge">useEffect</code></li> <li><a href="https://github.com/donavon/hook-flow">React Hooks Flowchart</a></li> </ul> </div></section> <section class="slide" id="links"><div><h2>Links</h2> <ul> <li><a href="https://react.dev/">React.js</a></li> <li><a href="https://roadmap.sh/react">React Developer Roadmap</a></li> <li><a href="https://usehooks.com/">useHooks</a></li> <li><a href="https://overreacted.io/react-as-a-ui-runtime/">Dan Abramov – React as a UI Runtime</a></li> <li><a href="https://ui.dev/imperative-vs-declarative-programming/">Imperative vs Declarative Programming</a></li> </ul> </div></section>