Labo 7
- Communicatie tussen componenten
1. Counter List
📂 Naam project:
lab-communication-counter-list
🔗 Basis project: n/a
We beginnen in deze oefening van de volgende code. Kopieer deze in een nieuw project en noem deze lab-communication-counter-list.
const CounterList = () => {
const [counters, setCounters] = useState<number[]>([]);
const addCounter = () => {
setCounters([...counters, 0]);
}
const increaseCounter = (index: number) => {
setCounters(counterCpy => counterCpy.map((counter, i) => (i === index) ? counter + 1 : counter));
}
const decreaseCounter = (index: number) => {
setCounters(counterCpy => counterCpy.map((counter, i) => (i === index) ? counter - 1 : counter));
}
return (
<>
{counters.map((counter, index) => {
let color = "black";
if (counter > 0) {
color = "green";
} else if (counter < 0) {
color = "red";
}
return (
<div style={{ display: "flex", flexDirection: "row", alignItems: "center", justifyContent: "center" }}>
<button onClick={() => decreaseCounter(index)}>Omlaag</button>
<div style={{ flex: 1, display: "flex", justifyContent: "center", alignItems: "center", color: color }}>Count: {counter}</div>
<button onClick={() => increaseCounter(index)}>Omhoog</button>
</div>
)
})}
<p>Som van de tellers: {counters.reduce((prev, curr) => prev + curr, 0)}</p>
<button onClick={addCounter}>Voeg teller toe</button>
</>
)
}
Dit is een implementatie van de CounterList component dat je in een voorgaande oefening hebt gemaakt. Hier was het nog niet de bedoeling om een aparte component te maken voor de Counter component. We gaan dit nu wel doen.
Maak een nieuwe component Counter aan. Deze component bevat een teller die je kan verhogen en verlagen. De Counter component bevat de volgende properties:
value: de waarde van de telleronIncrease: een callback functie die opgeroepen wordt als de teller verhoogd wordtonDecrease: een callback functie die opgeroepen wordt als de teller verlaagd wordtindex: de index van de teller in de lijst van tellers
Zorg er nu voor dat de CounterList component de Counter component gebruikt. De CounterList component bevat nog steeds de state van de tellers. De Counter component bevat geen state. De Counter component gebruikt de properties om de teller te tonen en de callbacks op te roepen.
Som van de tellers: 0
2. Todo App
📂 Naam project:
lab-communication-todo-app
🔗 Basis project: n/a
We beginnen van een voorgemaakte Todo app. Deze app bevat een lijst van taken die je kan toevoegen en verwijderen. De app bevat ook een input veld waar je een nieuwe taak kan toevoegen. Kopieer deze code in een nieuw project en noem deze lab-communication-todo-app.
import React, {useState} from "react";
interface TodoItem {
name: string;
completed: boolean;
}
const App = () => {
const [todos, setTodos] = useState<TodoItem[]>([]);
const [todo, setTodo] = useState("");
const addTodo = (todo: string) => {
setTodos([...todos, { name: todo, completed: false }]);
setTodo("");
};
const markCompleted = (index: number, completed: boolean) => {
setTodos(todos.map((todo, i) => i === index ? {...todo, completed: completed} : todo));
};
return (
<div>
<div>
<input id="todo" type="text" value={todo} onChange={(event) => setTodo(event.target.value)}/>
<button onClick={() => addTodo(todo)}>Add</button>
</div>
<div>
{todos.map((todo, index) => (
<div key={index}>
<input type="checkbox" checked={todo.completed} onChange={(event) => markCompleted(index, event.target.checked)}/>
<span style={{textDecoration: todo.completed ? "line-through" : "none"}}>{todo.name}</span>
</div>
))}
</div>
</div>
);
}
export default App;
Herstructureer deze applicatie als volgt:
- Maak drie nieuwe componenten aan in een aparte map
components:TodoListbevat de lijst van takenTodoItembevat een enkele taakTodoInputbevat het input veld en de knop om een taak toe te voegen
- Verplaats de logica van de
Appcomponent naar de nieuwe componenten - De state die de Todo's bevat moet in de
Appcomponent blijven. - Je zal dus moeten gebruik maken van
propsom de state door te geven aan de nieuwe componenten. Je zal ook gebruik moeten maken van child-to-parent communicatie om de state te kunnen updaten. - Zorg dat elk component in een aparte file staat.
Oplossingsvideo
3. Quizapp
📂 Naam project:
lab-communication-quiz-app
🔗 Basis project: n/a
Maak een nieuwe React applicatie aan en noem deze lab-communication-quiz-app.
- Maak een nieuw component
QuizAppaan. - Maak gebruik van de
https://opentdb.com/api.php?amount=10om de quizvragen op te halen. Gebruik defetchAPI om de data op te halen. Gebruik eenuseEffectom deze data op te halen en daarna in een state te plaatsen. - Er zijn twee soorten vragen: multiple choice en true/false. Maak een component
MultipleChoiceQuestionen een componentTrueFalseQuestionaan. Deze componenten worden gebruikt om de vragen te tonen. Maak een componentQuestionaan die de juiste vraag component toont op basis van het type vraag. - Als de gebruiker op een antwoord klikt wordt er aan de hand van een kleur aangegeven of het antwoord juist of fout is. Daarna wordt het antwoord getoond en kan de gebruiker niet meer van antwoord veranderen.
- Onderaan staat een button met de tekst 'Load More' die de volgende 10 vragen laadt. De vragen worden opnieuw opgehaald van de API. De vragen die al getoond of beantwoord zijn blijven in de lijst staan.
- Voorzie een loading indicator die getoond wordt tot de data geladen is (ook bij het laden van de volgende 10 vragen).
- Alle state moet in de
QuizAppcomponent zitten. DeQuestioncomponenten mogen geen state hebben. DeQuestioncomponenten moeten de state van deQuizAppcomponenten gebruiken via props en callbacks. - Maak gebruik van de
html-entitiespackage om de html entities te decoderen. Deze worden meegeleverd in de API. Anders krijg je bijvoorbeeld"te zien in plaats van".
Oplossingsvideo
4. Happy Workers
📂 Naam project:
lab-communication-happy-workers
🔗 Basis project: n/a
Maak een nieuwe React applicatie aan en noem deze lab-communication-happy-workers.
Plaats in de App component een progressbar (van 0 tot 100) en maak een component genaamd Square. Het Square component aanvaard initieel gewoon een color en een size prop. Later gaan hier nog props bij komen. Zorg ervoor dat je een aantal Square componenten toevoegd aan de App component met verschillende kleuren.
Maak een state work aan in de App component die initieel op 0 staat en de waarde voorstelt die de progressbar moet tonen.
Zorg ervoor dat als je op een Square klikt, de work state met 1 verhoogd wordt. Dit zorgt ervoor dat de progressbar met 1% verhoogd wordt.
Als de work state kleiner is dan 100 dan moet de Square component een 😐 tonen. Als de work state 100 is dan moet de Square component een 😃 tonen. Let er op: het tonen van de smileys vereist geen nieuwe state. Je kan dit afleiden van de work state.
😐
😐
😐
Uitbreiding:
- Maak een
stategenaamdproductivityaan in de Square component die initieel op 1 staat. Deproductivitystate stelt voor hoeveel procent deworkstate verhoogd wordt als je op deSquareklikt. - Dus als de
productivity1 is wordt bij elke klik deworkstate met 1 verhoogd. Als deproductivity2 is wordt bij elke klik deworkstate met 2 verhoogd. - Maak een
stategenaamdclickedaan in de Square component die initieel op 0 staat. - Als de
clickedstate groter of gelijk is aan 10 dan moet deproductivitystate op 0 gezet worden. Dit zorgt ervoor dat deSquarecomponent een 😵 toont. Het is dan tijdelijk niet meer mogelijk deworkstate te verhogen met dieSquare. - Na 5 seconden moet de
productivitystate terug op 1 gezet worden. Dit zorgt ervoor dat deSquarecomponent terug een 😐 toont. Ook declickedstate wordt terug op 0 gezet.
😐
😐
😐