פיתרון בעיות נפוצות בריאקט
בשיעור זה נעצור לדבר על מספר שגיאות מרכזיות שאנחנו עשויים לפגוש בעבודה עם ריאקט.
1. למה חשוב להתחיל עם שגיאות
אתם וודאי חושבים עכשיו - רק התחלנו את הקורס? איפה כבר אפשר לטעות? מה פתאום להתחיל עם תיקוני שגיאות לפני שלמדנו מה זה React. הדאגה אכן מובנת אבל יש סיבה לסדר המוזר: שיטת הלימוד היעילה ביותר לקוד היא התנסות. מסיבה זו בסוף כל שיעור אני מציע ניסויים קצרים שתוכלו לבצע, ובאופן כללי אני ממליץ ליצור גם לעצמכם תרגילים קצרים אפילו מעבר לדברים שאני מציע. בנוסף אני ממליץ בסיום כל שיעור שתכתבו ממש את הדוגמה שבניתי בשיעור אצלכם על המחשב כדי שתראו שאתם מסוגלים לבנות ולהריץ את הקוד גם בלי הוידאו.
הצד השני של גישה זו הוא שאתם הולכים להיתקל בבעיות, והרבה. כל שגיאת כתיב קטנה בתחילת הדרך נראית מלחיצה וכשדברים לא עובדים אנחנו לא יודעים עדיין להגיד אם יש לנו טעות משמעותית בהבנה או שהבעיה היא בסך הכל שגיאת כתיב קטנה. לכן בשיעור זה אתן לכם מספר כלים לחקור טוב יותר את התוכניות שאתם כותבים כדי שלא תיבהלו כשדברים ישברו.
2. שגיאות התקנה
סוג ראשון של שגיאות ומאוד נפוץ הוא שגיאות בהתקנת הכלים. המעבר מפיתוח Front End לפיתוח עם פריימוורק אומר שאנחנו צריכים להתקין כלי פיתוח על המחשב, בעיקר את node.js. בנוסף בכל החלק הראשון של הקורס אנחנו עובדים עם ריאקט באמצעות פריימוורק בשם next.js שגם היא דורשת התקנה. לכן בכל עבודה עם ריאקט כשמשהו לא עובד קודם כל כדאי לבדוק ש node.js מותקן באמצעות הרצת הפקודה הבאה משורת הפקודה:
node --version
התשובה צריכה לכלול מספר גירסה של node ונראית על המחשב שלי כך:
v20.12.2
אין בעיה אם יש לכם גירסה יותר חדשה. אם הגירסה ישנה מדי ודברים לא עובדים קודם כל כדאי לשדרג גירסת node.js.
גם לאחר שווידאתי ש node.js מותקן יצירת פרויקט יכולה להיכשל בעיקר בגלל בעיות רשת או בגלל שירותי סינון תכנים שלא מוגדרים נכון. אם אתם מפעילים את הפקודה:
npx create-next-app@latest first-react-app -e https://github.com/ynonp/next-15-starter
ומקבלים שגיאה או שהתיקייה first-react-app
לא נוצרה כדאי לנסות להריץ את הפקודה מחיבור אינטרנט אחר או לוודא עם ספק האינטרנט שלכם שהסינון עדיין מאפשר התקנת חבילות פיתוח מ npm.
3. שגיאות בניה
אחרי שהצלחנו ליצור פרויקט next חדש ולראות את סביבת הפיתוח בדפדפן הגיע הזמן לשבור קצת את הקוד, וההיבט הראשון שנשבור הוא מנגנון הבנייה. באפליקציית React הקומפוננטות כתובות בקבצים מיוחדים עם סיומת jsx או tsx. סביבת הפיתוח המקומית צריכה לבנות מקבצי מקור אלה קבצי JavaScript שאפשר לשלוח לדפדפן. שגיאות בניה הן כל השגיאות בגללן התהליך הזה נכשל.
נכנס לקוד לקובץ src/page.tsx
ונעדכן את תוכן הקובץ לקוד הבא:
export default function Home() {
return <p>Hello World
}
קל לראות ששכחתי לסגור את תגית ה p. בתגובה סביבת הפיתוח לא הצליחה לבנות את הפרויקט. השגיאה מופיעה בגדול על מסך הדפדפן מיד כשאני לוחץ "שמירה" בעורך הטקסט, ואם אני מנסה לרענן את העמוד אותה שגיאה תופיע גם בחלון המסוף. אותו דבר יקרה אם אני כותב תחביר JavaScript לא תקני לדוגמה מוחק את המילה function או חלק מהסוגריים.
שגיאות בניה הן השגיאות שהכי קל למצוא ולתקן כי אנחנו רואים את כל הפרטים בגדול על המסך.
4. שגיאות טייפסקריפט
בקורס נעבוד עם React ו TypeScript. טייפסקריפט הוא אופציונאלי בעבודה עם ריאקט - כשיצרנו תבנית פרויקט השאלה הראשונה של next היתה אם אנחנו רוצים להשתמש בטייפסקריפט וזה בסדר גם לענות שם בשלילה. אבל לטייפסקריפט כן יש מספר יתרונות בפיתוח ריאקט גם בזיהוי שגיאות נפוצות וגם בהשלמת קוד. גם אם אתם לא בקיאים בטייפסקריפט זה בסדר אני אסביר את הדברים תוך כדי תנועה ואני ממליץ בזמנכם הפנוי גם לקחת את קורס טייפסקריפט פה באתר שיעזור לכם לכתוב טייפסקריפט טוב יותר.
אחד הדברים הראשונים שטייפסקריפט מזהה הוא טעויות בטיפוסים, כלומר כשאנחנו מנסים לבצע על משהו מטיפוס אחד פעולה שלא מתאימה לו. הקלידו את הקוד הבא ב page.tsx
:
console.log('2' < 7);
export default function Home() {
return <p>Hello World</p>
}
בתור JavaScript הקוד תקין לגמרי - מחרוזת יכולה להיות גדולה או קטנה ממספר (ואתם יכולים לנחש לבד את המשמעות של פעולה זו), אבל טייפסקריפט יותר נוקשה ומוכן להשוות רק דברים מאותו טיפוס. לכן ב VS Code אני רואה קו אדום מתחת לפעולת ההשוואה, אבל מה שמעניין כאן זה שבדפדפן אני לא רואה שום סימן לבעיה. כלומר למרות שיש שגיאת טייפסקריפט, תהליך הפיתוח ממשיך כאילו אין בעיה ורק בשלב מאוחר יותר של בניית הפרויקט לסביבת פרודקשן אני אראה את הכישלון והשגיאה. התנהגות זו היא מכוונת ונועדה גם לגרום לפיתוח לעבוד מהר יותר וגם לאפשר לכם להתקדם בפיתוח בלי לתקן את כל שגיאות הטיפוסים מיד כשהן מופיעות, יחד עם זאת עלינו להיות ערניים לשגיאות אלה ובשלב ראשון אני ממליץ לוודא שאין קווים אדומים ב VS Code גם בזמן הפיתוח. אם אתם מתעקשים להשאיר קוד שטייפסקריפט לא אוהב ואתם בטוחים שהוא בסדר תמיד אפשר להשתיק את בדיקת הטייפסקריפט לשורה מסוימת עם פקודת @ts-ignore
או פקודת @ts-expect-error
באופן הבא:
// @ts-expect-error silence TS error
console.log('2' < 7);
export default function Home() {
return <p>Hello World</p>
}
בהגדרות ברירת המחדל של פרויקט חדש עלינו להשתמש ב @ts-expect-error
וגם לתאר מה השגיאה לה אנו מצפים בשורה הבאה. ניתן לשנות הגדרות אלה בקובץ eslint.config.mjs
וזה מחוץ לסקופ של קורס זה, כלומר במהלך הקורס נכתוב פרויקטים שיעבדו בהגדרות ברירת המחדל.
5. שגיאות בזמן ה Render
אחרי שהתגברנו על שגיאות הבניה אפשר לדבר על איך ריאקט עובד, לפחות בגדול. נזכור שריאקט מכריח אותנו לארגן את הדברים שאנחנו רואים על המסך בקומפוננטות. כרגע אנחנו כותבים רק קומפוננטה אחת בקובץ page.tsx
. הקומפוננטה היא פונקציה שמחזירה משהו שמורכב מתגיות JSX, כלומר תגיות שנראות כמו HTML אבל למעשה מגדירות אוביקטי JavaScript. בתוכנית ריאקט אנחנו נותנים לריאקט את הקומפוננטות שלנו, וריאקט מחליט מתי הוא מפעיל אותן ואיך הוא לוקח את מה שהפונקציות מחזירות וכותב את זה למסך. אנחנו עוד נדבר באריכות על תהליך זה של ריאקט אבל בינתיים חשוב להבין שבשביל שהתהליך יעבוד פונקציית קומפוננטה צריכה להחזיר משהו שריאקט יודע לעבוד איתו, ואם יש שגיאה במהלך ריצת פונקציית הקומפוננטה זה יהיה ריאקט שיתפוס את השגיאה. אגב לזמן הזה שבו ריאקט מריץ את פונקציות הקומפוננטה אנחנו קוראים render.
בואו נשבור את ה render ונעדכן את פונקציית הקומפוננטה לקוד הבא:
export default function Home() {
console.log((10).toFixed(-1));
return <p>Hello World</p>
}
פונקציית toFixed
של מספר מחזירה את המספר עם קיצוץ הספרות שאחרי הנקודה למספר שאנחנו מעבירים בתור פרמטר, לדוגמה:
> 10 / 3
3.3333333333333335
> (10 / 3).toFixed(2)
'3.33'
אבל אם מפעילים toFixed
ומעבירים מספר ספרות שלילי זו שגיאת זמן ריצה. אחרי שמירה וריענון אני מקבל בדפדפן הודעת שגיאה שנראית כך:
Unhandled Runtime Error
[ Server ] Error: toFixed() digits argument must be between 0 and 100
Source
src/app/page.tsx (2:20) @ Home
1 | export default function Home() {
> 2 | console.log((10).toFixed(-1));
| ^
3 | return <p>Hello World</p>
4 | }
5 |
השגיאה הפעם נקראת Unhandled Runtime Error בגלל שהיא התבצעה בזמן ריצה, בזמן שריאקט ניסה לעשות Render לקומפוננטה Home.
6. החזרת ערך לא נכון מ Render
פונקציית קומפוננטה חייבת להחזיר תגיות JSX או null. ערכים אחרים גורמים לשגיאות מוזרות אותן אנחנו רואים בפינה השמאלית תחתונה של המסך. נקליד את הקוד הבא בקוד הקומפוננטה:
export default function Home() {
return "hello"
}
ושימו לב שעכשיו על מסך הדפדפן יש לנו בצד שמאל למטה ריבוע אדום עם הכיתוב 1 error. לחיצה עליו מציגה את פרטי השגיאה:
Unhandled Runtime Error
Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used
- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
See more info here: https://nextjs.org/docs/messages/react-hydration-error
...
...
+ hello
- <text>
Show ignored frames
עוד דרך שבה קוד נשבר כשהוא מחזיר דברים לא נכונים מפונקציית קומפוננטה היא להחזיר שם אוביקט. נכתוב את הקוד הבא:
export default function Home() {
return {}
}
ועכשיו השגיאה על כל המסך:
Unhandled Runtime Error
Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.
למרות ההתנהגות השונה, הגורם לשתי הבעיות הוא אותה הבעיה - החזרת ערך לא נכון מפונקציית קומפוננטה.
7. התקנת כלי הפיתוח של ריאקט
תוסף דפדפן חשוב בעבודה עם ריאקט נקרא React Developer Tools. אני ממליץ להתקין אותו כבר עכשיו מהקישור הזה:
https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
אחרי ההתקנה נכנס לכלי הפיתוח לטאב Components ונוכל לראות את כל קומפוננטות ריאקט שיש לנו בעמוד. אתם כבר שמים לב שהקומפוננטה הקטנה שאנחנו בונים פה בדוגמה, page.tsx, היא רק חלק קטן מעץ קומפוננטות גדול שמנוהל ברובו על ידי next.js. במהלך הקורס נלמד יותר לעומק על אותן קומפוננטות של next ותפקידן בבניית אפליקציה. כרגע מספיק לראות את ההבדל בין עץ הקומפוננטות בטאב Components לעץ ה DOM בטאב Elements - זה ההבדל בין ה Virtual DOM של ריאקט לבין ההשפעה שלו על ה DOM האמיתי בדפדפן.
8. עכשיו אתם
מרגישים אבודים? יותר מדי שגיאות? הפיתרון הכי טוב הוא לשבור את הדברים עוד קצת. קחו את הזמן, צרו פרויקט חדש ונסו לשבור אותו בכל דרך שתמצאו. תראו אם תצליחו למצוא הודעות שגיאה שלא הראיתי כאן. אחרי שתתעייפו מלשבור ולתקן מוזמנים להמשיך לשיעור הבא.
שימו לב שאפשר לעבור לטאב ״טקסט״ כדי לקרוא את הטקסט המלא של השיעור ולראות את כל קוד הדוגמה בגירסת טקסט.
התקנת כלי הפיתוח של ריאקט:
https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi