תרגילים

תרגילים לתרגול כל הנושאים

הגיע הזמן להפוך את החומר לידע מעשי. התרגילים מסודרים לפי רמת קושי - מבסיסי ועד מתקדם. מומלץ לנסות לפתור כל תרגיל באופן עצמאי לפני שמציצים ברמז, ולבדוק את הפתרון מול הדוגמאות בתיקיית examples.


רמה בסיסית

תרגיל 1: קומפוננטת ברכה

צרו קומפוננטה Greeting שמקבלת prop בשם name ומציגה "שלום, [name]!"

// התוצאה הרצויה:
<Greeting name="דני" />  // מציג: שלום, דני!
💡 רמז השתמשו ב-function component עם props destructuring.

תרגיל 2: מונה לחיצות

צרו קומפוננטה Counter עם כפתור שסופר לחיצות.

// פונקציונליות:
// - מציג את מספר הלחיצות
// - כפתור "הוסף" שמגדיל ב-1
// - כפתור "אפס" שמחזיר ל-0
💡 רמז השתמשו ב-useState לניהול המונה.

תרגיל 3: Toggle

צרו קומפוננטה שמחליפה בין "פועל" ו"כבוי" בלחיצה על כפתור.

💡 רמז השתמשו ב-useState עם ערך בוליאני.

רמה בינונית

תרגיל 4: רשימת משימות

צרו אפליקציית רשימת משימות (Todo List) שכוללת:

  • שדה קלט להוספת משימה חדשה
  • רשימה של המשימות הקיימות
  • אפשרות למחוק משימה
  • אפשרות לסמן משימה כ"בוצעה"
💡 רמז
const [todos, setTodos] = useState([]);
// כל todo: { id, text, completed }

תרגיל 5: טופס הרשמה

צרו טופס הרשמה שכולל:

  • שדה שם (חובה, לפחות 2 תווים)
  • שדה אימייל (חובה, בפורמט תקין)
  • שדה סיסמה (חובה, לפחות 6 תווים)
  • הודעות שגיאה מתאימות לכל שדה
  • כפתור שליחה שפעיל רק כשכל השדות תקינים
💡 רמז השתמשו ב-state לכל שדה + state לשגיאות.

תרגיל 6: Timer

צרו טיימר שכולל:

  • תצוגת זמן בפורמט דקות:שניות
  • כפתור "התחל"
  • כפתור "עצור"
  • כפתור "אפס"
💡 רמז השתמשו ב-useEffect עם setInterval, ושמרו את ה-interval ב-useRef.

רמה מתקדמת

תרגיל 7: Fetch Data

צרו קומפוננטה שמביאה נתונים מ-API. הדרישות:

  • שליפת נתונים מהכתובת https://jsonplaceholder.typicode.com/users
  • הצגת מצב טעינה (loading) בזמן השליפה
  • הצגת הודעת שגיאה אם השליפה נכשלה
  • הצגת רשימת המשתמשים בסיום
💡 רמז
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
    fetch(url)
        .then(res => res.json())
        .then(data => setUsers(data))
        .catch(err => setError(err.message))
        .finally(() => setLoading(false));
}, []);

תרגיל 8: Theme Context

צרו מערכת ערכות נושא (Theme) המבוססת על Context:

  • שתי ערכות נושא: בהירה וכהה
  • כפתור להחלפה ביניהן
  • כל הקומפוננטות מתעדכנות בהתאם לערכה הפעילה
💡 רמז
const ThemeContext = createContext();

function ThemeProvider({ children }) {
    const [theme, setTheme] = useState('light');
    // ...
}

תרגיל 9: חנות (Mini E-Commerce)

צרו חנות מיני שכוללת:

  • רשימת מוצרים (שם, מחיר ותמונה)
  • אפשרות להוסיף מוצר לעגלה
  • תצוגת עגלה עם סכום כולל לתשלום
  • אפשרות להסיר מוצר מהעגלה

תרגיל 10: Custom Hook - useLocalStorage

צרו Custom Hook שעובד כמו useState אבל שומר את הנתונים ב-localStorage:

const [name, setName] = useLocalStorage('user-name', '');
// הערך נשמר גם אחרי רענון הדף!

טיפים לפתרון

  1. התחילו פשוט - קודם גרמו לזה לעבוד, אחר כך שפרו
  2. חלקו לקומפוננטות - כל חלק נפרד בקומפוננטה משלו
  3. בדקו תוך כדי - הריצו ובדקו אחרי כל שינוי קטן
  4. קראו את השגיאות - הן מספרות בדיוק מה הבעיה

פתרונות

הפתרונות נמצאים בתיקיית examples:

  • תרגילים 1-3: 01_hello_component.jsx
  • תרגיל 4: 08_todo_app.jsx
  • תרגיל 5: 04_events_example.jsx
  • תרגיל 6: 05_hooks_example.jsx

בהצלחה! 🎉


הקודם: ← רשימות
הבא: Lifecycle & useEffect →

בדקו את עצמכם

נסו לענות לבד לפני שאתם פותחים את התשובה.

  1. בנית רשימת משימות. איפה צריך להיות ה-state של המשימות?

    1. ב-localStorage בלבד
    2. במשתנה גלובלי
    3. בכל משימה בנפרד
    4. בקומפוננטה המשותפת הקרובה שצריכה אותו, ומשם עובר כ-props
    הצגת התשובה

    תשובה ד. כשכמה קומפוננטות צריכות את אותם נתונים, מרימים אותם להורה המשותף.

  2. טופס מבוקר (controlled) הוא טופס ש...

    1. אין לו state
    2. נשלח אוטומטית
    3. לא ניתן לעריכה
    4. הערך של כל שדה מגיע מ-state ומתעדכן ב-onChange
    הצגת התשובה

    תשובה ד. value={text} ו-onChange={e => setText(e.target.value)}.