Aufgabe 07-1a - Komponenten-Baukasten
Lernziele
Abschnitt betitelt „Lernziele“- Du zerlegst eine Oberfläche in eine sinnvolle Komponenten-Hierarchie und skizzierst sie samt Props.
- Du schreibst Komponenten in eigenen Dateien mit typisierten Props und exportierst sie benannt.
- Du renderst Listen mit
mapund einem stabilenkeyund leitest Sortierung und Kennzahlen beim Rendern aus den Daten ab. - Du weist nach, dass eine Komponente in einem zweiten Kontext unverändert arbeitet, und prüfst ihren Prop-Vertrag.
Ausgangslage
Abschnitt betitelt „Ausgangslage“Eine Pinnwand im Schulhaus hat niemand “programmiert”: Es gibt Zettel, die alle gleich aufgebaut sind, und jemand hängt sie auf. Genau so entsteht eine React-Oberfläche: Ein Baustein wird einmal entworfen und danach mit unterschiedlichen Daten immer wieder verwendet.
Du baust eine Klassen-Pinnwand mit Ankündigungskarten (siehe Kapitel React-Grundlagen, Einheiten 7.1 bis 7.3). Die Stufe Wesentlich_überwiegend passt nach Einheit 7.2 (JSX und Komponenten), die Stufe Wesentlich_vollständig nach Einheit 7.3 (Props, Listen und Events). Am Ende beweist du den Baukasten-Gedanken, indem dieselbe Karte unverändert in einem zweiten Kontext arbeitet.
Allgemein
Abschnitt betitelt „Allgemein“Projektordner anlegen siehe https://qiz.at/projektordner
-
Lies vorher kurz https://qiz.at/assignmentsabgabe durch.
-
Nur vollständige Abgaben (siehe https://qiz.at/rules) können positiv bewertet werden.
-
Abgabe- und Testdetails siehe https://qiz.at/assignmentsabgabe
-
Die Übung liegt als Unterordner
uebung-07-1ain deinem Jahres-RepositorySJ26_27_4AHITM_SEW_<Benutzername>_exercises. Du legst ihn wie in Einheit 7.1 als Vite-Projekt an und arbeitest allein:Terminal-Fenster npm create vite@latest uebung-07-1a -- --template react-tscd uebung-07-1anpm installnpm run dev -
Räum
src/App.tsxauf: Der Beispielinhalt der Vorlage (Logos, Zähler) fliegt raus, übrig bleibt ein leeres Gerüst. Jede Komponente kommt in eine eigene Datei untersrc/components/und wird benannt exportiert (export function AnnouncementCard ...). Vite kennt keine@/-Kurzschreibweise; importiert wird relativ (./components/Board,../data/announcements). -
Schriftliche Antworten stehen als Kommentar im Code.
npm run buildmuss fehlerfrei durchlaufen;node_modules/kommt nicht ins Repository. -
Next.js kommt erst in Kapitel 8 dazu: In einem Vite-Projekt läuft alles im Browser, es gibt keine Server-Komponenten und kein
"use client".
Wesentlich_überwiegend
Abschnitt betitelt „Wesentlich_überwiegend“Aufgabe
Abschnitt betitelt „Aufgabe“- Lege
src/data/announcements.tsan und definiere darininterface Announcementmitid, Titel, Text, Autor, Datum als ISO-String und Wichtigkeit als"normal" | "important". - Schreib drei Komponenten in eigenen Dateien:
AnnouncementCard({ announcement }: { announcement: Announcement })zeigt den Titel als Überschrift und den Text; darunterAuthorLinemit Autor und formatiertem Datum;ImportantBadgevor dem Titel, aber nur bei wichtigen Ankündigungen. - Render die Karte in
App.tsxzweimal mit zwei verschiedenen Testobjekten vom TypAnnouncement, um den Props-Mechanismus zu sehen. - Provozier den Compiler einmal bewusst: Setz in einem Testobjekt
importance: "wichtig". Notier die Meldung vonnpm run buildals Kommentar und mach die Änderung rückgängig. - Skizzier auf Papier die Hierarchie der ganzen Pinnwand:
App,Boardmit Kartenliste,AnnouncementCard, darinImportantBadgeundAuthorLine. Notier an jeder Komponente, welche Props sie braucht.
Tipp:
new Date(date).toLocaleDateString("de-AT")formatiert das Datum; die Formatierung gehört inAuthorLine, nicht als zusätzliches Prop. Typen holst du mitimport type, sonst bricht der Build mit TS1484 ab (Einheit 7.3). Bleibt die Seite weiß, prüf die Schreibweise im JSX: Komponenten beginnen mit einem Großbuchstaben.
Bewertungskriterien
Abschnitt betitelt „Bewertungskriterien“Vollständig, wenn:
npm run buildohne TypeScript-Fehler durchläuft, ohneanyund ohne untypisierte Props.- jede der drei Komponenten in einer eigenen Datei unter
src/components/liegt, benannt wie die Komponente und benannt exportiert. interface Announcementalle Felder abbildet, die Wichtigkeit als Union Type, und insrc/data/announcements.tsliegt.- das Badge nur bei wichtigen Ankündigungen erscheint und die Compiler-Meldung zu
"wichtig"als Kommentar notiert ist. - die Hierarchie-Skizze vorhanden ist, mit Props an jeder Komponente.
Wie unter Allgemein, dazu ein Foto der Hierarchie-Skizze.
Wesentlich_vollständig
Abschnitt betitelt „Wesentlich_vollständig“Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.
Aufgabe
Abschnitt betitelt „Aufgabe“Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieses Projekts (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):
- Leg in
src/data/announcements.tsfünf Ankündigungen als typisiertes Arrayannouncementsan (nicht in den Komponenten). Ersetz die Testobjekte inApp.tsxdurch eine KomponenteBoard, die die Daten als Prop bekommt und die Karten mitmaprendert. - Beantworte als Kommentar: Warum verlangt React ein
key-Prop, und warum ist der Array-Index dafür eine schlechte Wahl? - Wichtige Ankündigungen stehen oben: Sortier die Daten vor dem Rendern (sortierte Kopie!), statt zwei Listen zu pflegen.
- Ergänz eine Kopfzeile “n Ankündigungen, davon m wichtig”: Beide Zahlen werden beim Rendern aus dem Array berechnet, nirgends gespeichert.
- Halte in drei Kommentarsätzen fest, wie dieselbe Pinnwand mit direkter DOM-Manipulation aussähe (Elemente erzeugen, einhängen, bei Änderung wiederfinden und aktualisieren) und was React davon übernimmt.
Tipp:
sortverändert das Array, auf dem es aufgerufen wird; arbeite deshalb auf einer Kopie:[...announcements].sort(...). Die Liste zeigt nichts an? Mit runden Klammern nach dem Pfeil ((a) => (<li ...>)) wird der Rückgabewert automatisch geliefert, mit geschweiften brauchst du einreturn. Daskey-Attribut gehört an das äußerste Element innerhalb vonmap.
Bewertungskriterien
Abschnitt betitelt „Bewertungskriterien“Vollständig, wenn:
- die fünf Ankündigungen in
src/data/announcements.tsliegen undBoardsie mitmapund einem stabilenkeyaus den Daten (nicht dem Index) rendert. - die Antwort zur Key-Frage dokumentiert ist.
- Sortierung und Kennzahlen beim Rendern abgeleitet sind; es gibt keine zweite gespeicherte Liste und keinen Zähler im Code.
- keine Komponente auf
document.zugreift und der Vergleich mit der DOM-Manipulation in drei Sätzen notiert ist.
Wie unter Allgemein, dazu ein Screenshot der laufenden Pinnwand inklusive Browser-Adresszeile.
PlusPlus Aufgabe
Abschnitt betitelt „PlusPlus Aufgabe“Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.
Aufgabe
Abschnitt betitelt „Aufgabe“Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieses Projekts (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):
- Zweiter Einsatzort: Eine Komponente
Archivezeigt dieselben Karten kompakt (nur Titel, Badge und Autorzeile). Steuer das über ein optionales Propcompact?: booleanmit Standardwertfalse; die Karte bleibt eine Komponente, und die Pinnwand-Variante ändert sich nicht. - Review des eigenen Prop-Vertrags: Prüf
AnnouncementCardgegen zwei Kriterien. Braucht die Karte alles, was sie bekommt? Bekommt sie nichts, was sie sich selbst ausrechnen könnte? Dokumentier einen gefundenen Verstoß samt Korrektur oder begründe die Vertragsqualität als Kommentar.
Tipp: Ein Prop ohne Fragezeichen und ohne Standardwert zwingt dich, jede bestehende Verwendungsstelle zu ändern. Genau das darf der zweite Einsatzort nicht verlangen.
Bewertungskriterien
Abschnitt betitelt „Bewertungskriterien“Vollständig, wenn:
compactoptional mit Standardwert ist, das Archiv dieselbe Karte verwendet und die Pinnwand unverändert bleibt.- das Prop-Vertrags-Review nachvollziehbar dokumentiert ist.
Wie unter Allgemein.
MandalorianPlus Aufgabe
Abschnitt betitelt „MandalorianPlus Aufgabe“Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.
Aufgabe
Abschnitt betitelt „Aufgabe“Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieses Projekts (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):
- Härterer Test: Die Karte soll im Archiv beim Klick aufklappen können (dann mit Text), ohne dass sich die Pinnwand-Variante ändert. Entscheide: Gehört dieser Zustand in die Karte oder in das Archiv? Setz deine Antwort mit
useStateum und begründe sie in zwei Sätzen. - Beurteile in zwei Sätzen: Woran erkennt man an dieser Übung, dass Komponenten das Gegenstück der Oberfläche zu Funktionen sind?
Tipp:
useStatekommt erst in Einheit 7.4 ausführlich; für diese Stufe genügtconst [expanded, setExpanded] = useState(false);ganz oben in der Komponente, nicht in einemif. Für die Entscheidung hilft die Frage: Wer außer der Karte liest oder ändert diesen Zustand?
Bewertungskriterien
Abschnitt betitelt „Bewertungskriterien“Vollständig, wenn:
- das Aufklappen im Archiv funktioniert und die Pinnwand-Variante unverändert ist.
- die Zustandsentscheidung mit einer Begründung belegt ist, die zur Umsetzung passt.
- die Beurteilung zu Komponenten und Funktionen stichhaltig ist.
Wie unter Allgemein.
Wissenscheck
Abschnitt betitelt „Wissenscheck“- Was sind Props, und warum darf eine Komponente ihre eigenen Props nicht ändern?
- Wozu braucht React das
key-Prop bei Listen? - Warum wird die Wichtig-Sortierung vor dem Rendern berechnet statt als zweite Liste gespeichert?
- Was bewirkt
bedingung && <ImportantBadge />in JSX? - Wann lohnt ein optionales Prop wie
compact, und wann wäre eine zweite Komponente ehrlicher? - Warum muss ein Komponentenname mit einem Großbuchstaben beginnen?
Zeit dafür
Abschnitt betitelt „Zeit dafür“Durchschnittlich bis Wesentlich_vollständig: ca. 100 min
Autoren
Abschnitt betitelt „Autoren“- Oliver Maurhart (MAO)
- Michael Gabriel (GAM)
CC-BY-SA