יום 5 בלימוד React: Batching ועדכונים פונקציונליים (Functional Updates)
חשבתי שקריאה ל-state setter מספר פעמים גורמת למספר רינדורים (renders).
טעיתי.
React חכמה יותר מזה. היא משתמשת בתהליך שנקרא Automatic Batching.
במקום לבצע רינדור אחרי כל עדכון בודד, React מקבצת אותם יחד. היא אוספת את כל העדכונים ומבצעת רינדור אחד בלבד. זה חוסך במשאבים ומשפר ביצועים.
הנה מה שלמדתי היום.
The Batching Process כשקוראים למספר פונקציות state, React פועלת לפי התזרים הבא:
- מתרחשים מספר עדכוני state.
- React מקבצת אותם יחד.
- React מבצעת רינדור אחד.
- React מחילה (commits) את השינויים על ה-UI.
The Problem with Standard Updates
ניסיתי את הקוד הזה:
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
ציפיתי שה-count יעלה מ-0 ל-3. הוא עלה מ-0 ל-1.
זה קורה כי setCount(count + 1) לא אומר "תגדיל את ה-count".
הוא אומר "תקבע את ה-count לערך הספציפי הזה".
אם ה-count הוא 0, כל שורה אומרת ל-React לקבוע את ה-count ל-1. React מקבצת את הפעולות הללו ורואה שההוראה האחרונה היא לקבוע את ה-count ל-1.
The Solution: Functional Updates כדי לתקן זאת, עליך להשתמש ב-functional update. זה משתמש ב-state העדכני ביותר הזמין בתור העדכונים (update queue).
הדרך הנכונה:
setCount((prev) => prev + 1);
כשמשתמשים בתבנית הזו, React נותנת לכל עדכון את הערך הכי עדכני.
- עדכון ראשון: 0 + 1 = 1
- עדכון שני: 1 + 1 = 2
- עדכון שלישי: 2 + 1 = 3
עכשיו המונה באמת מגיע ל-3.
A Common Mistake
פעם כתבתי:
setCount((prev) => { prev + 1 });
המונה הפך ל-undefined.
כשמשתמשים בסוגריים מסולסלים בתוך arrow function, חייבים להשתמש במילת המפתח return.
השתמשו בזה במקום:
setCount((prev) => prev + 1);
Key Takeaways:
- React מקבצת מספר עדכוני state כדי לשפר את המהירות.
- קריאות ל-
setStateלא תמיד מפעילות רינדורים מיידיים. - עדכונים סטנדרטיים משתמשים בערך מתוך מחזור הרינדור הנוכחי.
- עדכונים פונקציונליים משתמשים ב-state העדכני ביותר מתוך תור העדכונים.
- React משתמשת ב-Update Queue פנימי כדי לנהל את השינויים הללו.
