Aufgabe 13 - Quiz reloaded
Aufgabe 13 - Quiz reloaded
Abschnitt betitelt „Aufgabe 13 - Quiz reloaded“Worum geht es?
Abschnitt betitelt „Worum geht es?“Die erste vollständige React-Anwendung: ein Multiple-Choice-Quiz mit Phasen, Punktestand und Auswertung. Die Übung führt alles zusammen, was die React-Wochen aufgebaut haben (State modellieren, Events, bedingtes Rendern), und ergänzt mit einem eigenen Hook die Hook-Familie um ein selbstgebautes Mitglied (siehe Kapitel React-Grundlagen).
Was Sie dafür brauchen
Abschnitt betitelt „Was Sie dafür brauchen“- Kapitel React-Grundlagen vollständig; Aufgaben 11 und 12.
- Das Next.js-Projekt aus Aufgabe 11/12 (oder ein frisches über
npx create-next-app@latest, siehe Aufgabe 11); ein Vorgriff auf Kapitel 8. Next.js I - Struktur und Routing. Zum Vergleich in Teil D wird eine imperative Vanilla-JavaScript-Fassung desselben Quiz ausgeteilt.
Welche Kompetenzen Sie erwerben und zeigen
Abschnitt betitelt „Welche Kompetenzen Sie erwerben und zeigen“- Sie modellieren den Zustand einer kleinen Anwendung vollständig vor der Implementierung.
- Sie setzen Ablauflogik ausschließlich über State und bedingtes Rendern um.
- Sie kapseln wiederverwendbare Logik in einem eigenen Hook.
Pädagogische Einordnung
Abschnitt betitelt „Pädagogische Einordnung“- Reproduktion: das Zustandsmodell nach dem Kapitelmuster aufstellen (Teil A).
- Reorganisation und Transfer: Modell und Muster in eine lauffähige Anwendung überführen (Teile B und C).
- Reflexion, Problemlösung und Urteilsbildung: deklarativen und imperativen Ansatz vergleichen und die Unterschiede bewerten (Teil D).
Arbeitsaufträge
Abschnitt betitelt „Arbeitsaufträge“Die Übung ist auf etwa zwei Stunden ausgelegt. Teil D ist der Expertenteil.
So richten Sie die Quiz-Seite ein (einmal am Anfang, dann geht es los):
- Legen Sie im Projekt den Ordner
app/quiz/an und darin eine Dateipage.tsx. Diese Seite erreichen Sie im Browser unterhttp://localhost:3000/quiz, sobald der Entwicklungsserver läuft (npm run dev). - Die Quiz-Komponente schreiben Sie in eine eigene Datei, etwa
app/quiz/Quiz.tsx. Weil das QuizuseStateverwendet, braucht diese Datei ganz oben die Zeile"use client";(sonst läuft sie als Server-Komponente unduseStatebricht ab). - In
page.tsximportieren Sie die Komponente und übergeben ihr die Fragen. Die Fragendateilib/questions.tslegen Sie erst in Teil B an; bis dahin genügt eine kurze Platzhalterliste direkt inpage.tsx, damit die Seite anzeigbar ist:
import { Quiz } from "./Quiz";// import { questions } from "@/lib/questions"; // wire this up in part B
const questions = [ { text: "2 + 2 = ?", answers: ["3", "4", "5"], correctIndex: 1 },];
export default function QuizPage() { return ( <main> <Quiz questions={questions} /> </main> );}In Teil B verschieben Sie die Fragen dann nach lib/questions.ts und ersetzen die Platzhalterliste durch den auskommentierten Import. Bauen Sie in der Reihenfolge der Teile: erst das Zustandsmodell auf Papier (Teil A), dann die laufende Anwendung (Teil B), dann den Hook (Teil C).
Teil A - Zustandsmodell zuerst
Abschnitt betitelt „Teil A - Zustandsmodell zuerst“- Bestimmen Sie vor der ersten Codezeile die State-Variablen des Quiz. Kandidaten: Nummer der aktuellen Frage, Punktestand, gewählte Antwort, Phase als Union Type
"running" | "feedback" | "finished". - Prüfen Sie jede Variable gegen die Regel aus Aufgabe 12: Ist sie echter State oder ableitbar? (Die Anzeige “Frage 3 von 8” etwa ist ableitbar.)
- Skizzieren Sie den Ablauf als Zustandsdiagramm: Phasen als Zustände, Benutzeraktionen als Übergänge (Antwort geklickt, Weiter, Nochmal).
Teil B - Implementieren
Abschnitt betitelt „Teil B - Implementieren“- Typisierte Fragenstruktur (
interface Questionmit Text, drei Antworten, Index der richtigen), mindestens acht Fragen inlib/questions.ts. - Ablauf: eine Frage mit drei Antwort-Buttons; nach dem Klick Phase
feedback(richtig grün, falsch rot, richtige Antwort markiert; Buttons deaktiviert), Button “Weiter”; nach der letzten Frage Phasefinishedmit Prozentwert, Kommentar und “Nochmal”. - Verbindliche Regel: kein direkter DOM-Zugriff (
document.ist verboten); jede Ansicht folgt aus Phase und State über bedingtes Rendern. - Fortschrittsanzeige und Punktestand sind immer aktuell, ohne dass irgendwo “aktualisiert” wird; halten Sie im Kommentar fest, warum das im deklarativen Modell automatisch gilt.
Teil C - Ein eigener Hook
Abschnitt betitelt „Teil C - Ein eigener Hook“- Der beste Punktestand soll Neustarts der Seite überleben: Schreiben Sie den Hook
useLocalStorage(key, initial)nach dem Muster des Kapitels und verwenden Sie ihn für ein “Best: n %” in der Auswertung. - Der Hook wohnt in
lib/use-local-storage.tsund ist quizfrei formuliert (keine Quiz-Begriffe): Er muss unverändert auch in einer anderen Anwendung funktionieren. - Beachten Sie die Client-Grenze:
localStorageexistiert nur im Browser; die betroffene Komponente braucht"use client".
Teil D - Expertenteil: Der Vergleich
Abschnitt betitelt „Teil D - Expertenteil: Der Vergleich“- Lesen Sie die ausgeteilte imperative Vanilla-JS-Fassung desselben Quiz (direkte DOM-Manipulation, Event-Listener, manuelle Anzeigen-Updates) und bringen Sie sie lokal zum Laufen.
- Bauen Sie in beide Fassungen dieselbe kleine Erweiterung ein: Nach einer falschen Antwort zeigt eine Zeile “davon richtig: k von n”. Protokollieren Sie je Fassung, welche Stellen Sie anfassen mussten.
- Schreiben Sie den Vergleich (fünf bis acht Sätze): Wo steckt im imperativen Ansatz die meiste Arbeit? Welche Fehlerklasse verschwindet deklarativ (Stichwort: vergessene Anzeige-Updates)? Und ehrlich: Gibt es etwas, das imperativ einfacher war?
- Zusatz: Provozieren Sie in der React-Fassung einen Key-Fehler (Antworten-Liste mit Index als Key rendern und die Antworten mischen) und dokumentieren Sie den sichtbaren Effekt.
Wissenscheck
Abschnitt betitelt „Wissenscheck“- Warum ist die Phase als Union Type besser modelliert als mit zwei Booleans (
isFinished,showFeedback)? - Welche Werte des Quiz sind abgeleitet und dürfen keinen eigenen State haben?
- Warum sind die Antwort-Buttons in der Feedback-Phase deaktiviert, und wie erreicht man das deklarativ?
- Warum braucht die Komponente mit
useLocalStoragedie Direktive"use client"? - Welche Fehlerklasse des imperativen Ansatzes verhindert React strukturell?
Projekt als Git-Repository, das Zustandsdiagramm, das Erweiterungsprotokoll und der schriftliche Vergleich aus Teil D.