9.4 שליפת נתונים וסרבר אקשנס תרגול
תרגול - שליפת נתונים וסרבר אקשנס - Data Fetching and Server Actions¶
תרגיל 1 - שליפת נתונים מ-API¶
צרו דף שמציג רשימת משתמשים מ-API חיצוני:
- שלפו נתונים מ-
https://jsonplaceholder.typicode.com/users - הציגו: שם, אימייל, עיר, וחברה
- עצבו כל משתמש ככרטיס (card)
- הוסיפו אופציית
revalidateשל 3600 שניות (שעה)
תרגיל 2 - דף פוסט עם תגובות¶
צרו דף שמציג פוסט בודד עם התגובות שלו:
- שלפו פוסט מ-
https://jsonplaceholder.typicode.com/posts/{id} - שלפו תגובות מ-
https://jsonplaceholder.typicode.com/posts/{id}/comments - עטפו את התגובות ב-Suspense עם fallback של skeleton
- הנתיב יהיה
/posts/[id]
רמז - שימוש ב-Promise.all לשליפה מקבילית:
const [post, comments] = await Promise.all([
fetch(`...posts/${id}`).then(r => r.json()),
fetch(`...posts/${id}/comments`).then(r => r.json()),
]);
תרגיל 3 - טופס יצירת משימה עם Server Action¶
צרו מערכת משימות (TODO) עם Server Actions:
- צרו קובץ
actions.tsעם הפונקציות:addTodo,toggleTodo,deleteTodo - צרו דף שמציג את רשימת המשימות
- הוסיפו טופס להוספת משימה חדשה (שימוש ב-form action)
- הוסיפו אפשרות למחיקה וסימון כ"בוצע"
- השתמשו ב-
revalidatePathלעדכון הדף
דמו בסיס נתונים עם מערך:
// lib/todos.ts
let todos = [
{ id: 1, title: "ללמוד Next.js", completed: false },
{ id: 2, title: "לבנות פרויקט", completed: false },
];
export function getTodos() { return todos; }
export function addTodo(title: string) { /* ... */ }
export function toggleTodo(id: number) { /* ... */ }
export function deleteTodo(id: number) { /* ... */ }
תרגיל 4 - סטרימינג עם Suspense¶
צרו דף דשבורד עם שלושה אזורים שנטענים בנפרד:
WeatherWidget- מדמה שליפת מזג אוויר (השהייה של 1 שניה)NewsWidget- מדמה שליפת חדשות (השהייה של 2 שניות)StatsWidget- מדמה שליפת סטטיסטיקות (השהייה של 3 שניות)
כל אחד עטוף ב-Suspense עם skeleton. צפו בטעינה ההדרגתית.
תרגיל 5 - טיפול בשגיאות¶
שפרו את מערכת המשימות מתרגיל 3:
- הוסיפו ולידציה ב-Server Action (אורך מינימלי, אין כפילויות)
- החזירו אובייקט תוצאה עם success/error
- הציגו הודעות שגיאה בטופס
- הוסיפו אנימציית loading בזמן שליחת הטופס (useFormStatus)
רמז:
import { useFormStatus } from "react-dom";
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button disabled={pending}>
{pending ? "שולח..." : "שלח"}
</button>
);
}
תרגיל 6 - קאשינג ועדכון¶
צרו דף שמציג שעה ותאריך נוכחיים מהשרת, ותרגלו קאשינג:
- צרו פונקציה שמחזירה את הזמן הנוכחי מהשרת
- צרו שלושה אזורים בדף:
- אזור סטטי (cache: force-cache) - הזמן לא מתעדכן
- אזור דינמי (cache: no-store) - הזמן מתעדכן בכל ריענון
- אזור ISR (revalidate: 10) - הזמן מתעדכן כל 10 שניות
- הוסיפו Server Action עם revalidatePath שמאפשר ריענון ידני
שאלות¶
- מה ההבדל בין שליפת נתונים ב-Server Component לעומת useEffect ב-Client Component?
- מתי נשתמש ב-
cache: "no-store"לעומתrevalidate? - מה היתרון של Server Actions על פני API Routes?
- מה Suspense עושה מאחורי הקלעים בהקשר של סטרימינג?
- למה Server Actions תומכים ב-Progressive Enhancement?