useEffect בריאקט מוסבר בפשטות¶
אם יש הוק אחד בריאקט שגורם לאנשים לרצות לזרוק את המקלדת, זה useEffect. הוא נראה פשוט בדוגמאות באתר הרשמי, ואז ברגע שאתם מנסים להשתמש בו בפרויקט אמיתי שלכם, פתאום יש לולאות אינסופיות, בקשות רשת שרצות פי שלוש ממה שציפיתם, ותחושה כללית שאתם לא מבינים מה קורה. בואו נסדר את זה מהיסוד.
מה הבעיה ש-useEffect בא לפתור¶
קומפוננטה בריאקט היא בעיקרה פונקציה שמחזירה ממשק. אבל לפעמים אתם צריכים לעשות דברים שהם לא "לצייר ממשק" - להביא נתונים משרת, להירשם לאירוע, להתחיל טיימר, לעדכן את כותרת הדף. את כל אלה קוראים בריאקט "תופעות לוואי" (side effects), כי הן משפיעות על משהו שהוא מחוץ לתהליך הרגיל של רינדור הממשק.
useEffect הוא הדרך של ריאקט להגיד "תריץ את הקוד הזה אחרי שהקומפוננטה סיימה להצטייר על המסך". זהו, זה כל הרעיון. לא יותר מזה.
דוגמה פשוטה¶
import { useState, useEffect } from "react";
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then((res) => res.json())
.then((data) => setUser(data));
}, [userId]);
if (!user) return <p>טוען...</p>;
return <h1>{user.name}</h1>;
}
הקומפוננטה מצטיירת, ואז ה-useEffect רץ ומביא את המשתמש מהשרת. כשה-userId משתנה, ה-effect רץ שוב ומביא נתונים חדשים.
מה זה מערך התלויות (dependency array)¶
זה החלק שכולם מתבלבלים בו - המערך הזה, [userId] בדוגמה למעלה. ריאקט משווה את הערכים במערך הזה בין רינדור לרינדור, ואם משהו השתנה, הוא מריץ את ה-effect שוב.
שלושה מצבים שחשוב להכיר:
- בלי מערך בכלל - ה-effect רץ אחרי כל רינדור, בלי יוצא מן הכלל. כמעט תמיד זו טעות.
- מערך ריק
[]- ה-effect רץ פעם אחת בלבד, כשהקומפוננטה נטענת לראשונה. שימושי להבאת נתונים ראשונית. - מערך עם ערכים
[userId]- ה-effect רץ בכל פעם שאחד הערכים במערך משתנה.
המלכודת הכי נפוצה - לולאה אינסופית¶
הנה טעות שכל מתחיל עושה לפחות פעם אחת:
ה-effect משנה את count, מה שגורם לרינדור מחדש, מה שגורם ל-effect לרוץ שוב, מה שמשנה את count שוב, וחוזר חלילה. הדפדפן נתקע, הפאן שלכם מתחיל לרעוש, וזה קורה כמעט לכולם בפעם הראשונה. הכלל הפשוט - אל תעדכנו בתוך ה-effect משהו שנמצא במערך התלויות שלו, אלא אם יש לכם תנאי ברור שעוצר את זה.
מתי לא צריך useEffect בכלל¶
זו אולי הנקודה הכי חשובה, ואף אחד לא אומר אותה מספיק: הרבה פעמים אתם משתמשים ב-useEffect כשבכלל לא הייתם צריכים. אם אתם רק רוצים לחשב ערך על סמך state קיים, פשוט תחשבו אותו ישירות בגוף הקומפוננטה, בלי effect בכלל:
הכלל הזהב - useEffect הוא לדברים שקשורים לעולם שמחוץ לריאקט (רשת, טיימרים, DOM ישיר, מנויים חיצוניים). אם זה רק חישוב על סמך state, אתם לא צריכים אותו.
איך לזכור את זה נכון¶
אני אוהב להסביר את זה ככה: הקומפוננטה שלכם היא כמו טופס שאתם ממלאים על פי מידע שיש לכם. useEffect זה הרגע שבו, אחרי שמילאתם את הטופס, אתם יוצאים החוצה לעולם - לדואר, לטלפון - כדי להביא מידע חדש שישפיע על הטופס בפעם הבאה.
זה נושא שדורש תרגול אמיתי כדי שיתיישב, ולא רק קריאה. בקורס צד לקוח יש פרק שלם על ריאקט מתקדם וניהול סטייט, עם תרגילים שבנויים בדיוק כדי לתפוס את המלכודות האלה לפני שהן תופסות אתכם בעבודה.
לסיכום¶
useEffect הוא לא מפלצת, הוא כלי לתופעות לוואי - דברים שקורים אחרי שהממשק כבר על המסך. תבינו את מערך התלויות, תיזהרו מלולאות, ותשאלו את עצמכם קודם אם אתם בכלל צריכים אותו. ברגע שהמודל המנטלי הזה מתיישב, useEffect הופך מהאויב הכי גדול שלכם לכלי הכי שימושי בארגז.
יש לכם קוד שנתקע בלולאה אינסופית ואתם לא מבינים למה? תביאו אותו לדיסקורד, זה בדיוק המקום לזה.