עזרה בהבנה בסיסית של useRef, useEffect,useState
קדם ‹ Forums ‹ הייטק ‹ Web Development ‹ עזרה בהבנה בסיסית של useRef, useEffect,useState
-
עזרה בהבנה בסיסית של useRef, useEffect,useState
פורסם ע"י שושי הייטק on 27/08/2023 ב4:44 amהיי,
אני באמצע לכתוב פרויקט בריאקט ונתקלתי בכמה בעיות שגרמו לי להבין שאני לא בדיוק מבינה את המושגים האלו…
הבנתי ש useRef בעצם מאחסן לי בדביקות את הערך, וכשרציתי לנקות טופס, מכפתור שנלחץ מקומפוננטה אחרת לא עזר לו כלום והוא פשוט שמר על הערך בשדות של הinputs..
useEffect- אם הבנתי נכון זה בעצם הוקס שנועד לעדכן אם יש שינויים במשתנים של props וצריך לעדכן אותם.
useState- אמור לעדכן לי בזמן אמת את המשתנה בדפדפן . ומשום מה כשאני כותבת את הקוד הזה ומדבגת:
רק אחרי שאני לוחצת פעמיים על האייקון, הערך שלו משתנה…
אשמח לדעת מה מכל מה שהבנתי היה שטויות…🙃
וגם לעזרה במציאת הבעיה.
תודה רבה!!!
שושי הגיבה לפני 1 שנה, 3 חודשים 4 חברות · 12 תגובות -
12 תגובות
-
האמת שעכשיו הבנתי, שuseState מעדכן לא מיד, אבל אם אני רוצה שהוא יתעדכן מיד אני צריכה להגדיר אותו בuseEffect…
ככה לפחות עבד לי עכשיו השאלה השניה…
אם יש למישי משהו להוסיף או להבהיר אני מאד אשמח!
תודה רבה!!
-
את צריכה לשנות את הפונקציה handleIconSearch
-
בשביל מה את מחזיקה שני משתנים נפרדים – wordSearch וfilterInfo
אם שניהם תמיד משתנים ביחד ומקבלים את אותו ערך?-
כי אחד זה משתנה שמכיל כל פעם את התוכן של input שמתעדכן בהקשת כל מקלדת, ואני צריכה שרק כשהוא ילחץ הוא ייקח לי את כל המילה ממנו.
-
למעשה שניהם מתעדכנים תמיד ביחד.
יש מקום אחר בקוד שרק אחד מהם מתעדכן?
אני לא מבינה את הלוגיקה.
אבל אם עובד לך – מצוין.
-
כן, עובד, הקוד שהראיתי זה הקוד שלוחצים על הכפתור, שרוצים לחפש את כל המילה….
וב”ה זה עובד….
בקשר לשאלה הראשונה אין לאף אחת מושג?
פליזזז
-
-
-
-
היי
יש לי כמה חומרים על הנושא
שמה לך פה
מתנצלת שאין לי זמן לסנן רק את מה שרלוונטי, (הדגשתי משפטי מפתח)
אבל נראה לי עונה על רוב השאלות שלך..
(ואגב, אשמח לשמוע הערות והארות 🙂 )
Web components – קומפוננטות- רכיבים – אוסף של טכנולוגיות שונות שמאפשרות ליצור אלמנטים מותאמים אישית וניתנים לשימוש חוזר.
-
Custom elements – היכולת ליצור אלמנטים מותאמים אישית שניתנים לשימוש חוזר. למשל אם יש לנו תפריט בעמודים ובאזורים שונים נוכל ליצור רכיב שייקרא בשם menu , ניתן לרכיב את כל הערכים שהוא זקוק להם, ובכל פעם נוכל לקרוא ל<menu></menu> ולקבל את תוכן האלמנט כפי שהוגדר.
-
Shadow dom- היכולת לשמור על כל רכיב כישות בפני עצמה, עם קוד ועיצוב משל עצמה
-
Html template – דפי תבנית של HTML שיהיו מיועדים עבור הקומפוננטות. היכולת לכתוב למשל <menu></menu> שלא יוצג כך , אלא ירונדר לתוכן הרכיב.
אפשר להתייחס לקומפוננטות שלנו כ’עץ קומפוננטות’. יש לנו את הקודקוד, בד”כ קומפוננטת הapp והיא מרנדרת את כל הקומפוננטות שהיא מכילה, כל אחת מהן כשהיא מתרנדרת מרנדרת את כל הבנים שלה וכן הלאה… סוג של עץ, עם היררכיה של אב ובן. האב הוא הקומפוננטה, הבן הוא הקומפוננטה שהאב מרנדר. כך:
Function Parent(){
Return <ChildComponent />
}
בעצם מה שקרה- האב – קומפוננטת הParent כשתרונדר- הפונקציה תחזיר את הבן, מה שירנדר גם אותו. כמובן, אם לבן ישנם עוד בנים – גם הם ירונדרו.. והלאה..
-
לפעמים, או אפשר לומר שבדרך כלל – לקומפוננטה ישנה התנהגות שתלויה במידע חיצוני שהיא תקבל. (למשל קומפוננטה שמציגה “שלום ל<שם>” עבור כל שם שתקבל. ) הקומפוננטה צריכה לקבל מידע רלוונטי ממי ש’יצר’ אותה. האב שולח לבנו את המידע שהוא זקוק לו דרך הprops. בעצם כמו שלכל אלמנט רגיל יש לנו פרופרטיז כמו src ל img , hrefל a, כך גם לקומפוננטה יש ‘הגדרות נוספות’ שמקבלת מקומפוננטת האב. כמו כל פרופרטי – נכתוב כך <Hello name=”Adina”/> ואז הבן יקבל פרופרטי בשם name שיכיל בתוכו את המידע “Adina” ויוכל להשתמש בו.
איך משתמשים במידע שהגיע? כמו כל פרמטר חיצוני שמגיע לפונקציה. Function Hello(props) {} מקובל לקרוא למשתנה המכיל את הערכים שנשלחו מהאב בשם props. זה בעצם אובייקט שמכיל את כל שמות הפרופרטיז שנשלחו ואת ערכיהם.
במקרה זה: props = { name : “Adina”}
ונוכל לגשת אל הערך: props.name .
חשוב! אף פעם לא משנים ערך של משתנה שהגיע דרך ה props.
-
ניהול ארועים בריאקט – אפליקציה היא דבר דינאמי, שאופן התנהגותו לפי פעולות של המשתמש. ערכים שונים משתנים ומשפיעים על הפעולה של האפליקציה.
המקרה הסטנדרטי לשינויי ערכים אלו ארועים, פעולות של המשתמש onClick, onBlur …
בעת פעולה של ארוע נרצה שתקרה פונקציה מסוימת. ניצור פונקציית עדכון הערך וכערך המאפיין נשלח שם הפונקציה כך : <input onBlur={setUser}/>
או במקרה שבו הפונקציה פשוטה, נוכל לכתוב אותה כבר כערך המאפיין בתחביר חץ כך: <input onChange={e => props.setUser(e.target.value)}/>
כפי שנכתב לעיל אין לשנות משתנה פרופס בשום אופן! לכן אם יש צורך לשנות משתנה כזה, אז באותו מקום שהוגדר המשתנה, ניצור פונקציית עדכון, ונשלח גם אותה בפרופס.
-
State יש לנו בעצם משתנים בריאקט שאמורים בעת שינוי להשתנות בתצוגה, לפי קלט מהמשתמש או מסיבה אחרת. בעצם גוררות אחרי השינוי שלהן צורך בעדכון שלהן. ריאקט לא מרנדרת בכל שינוי את כל התצוגה, כי זו פעולה כבדה מאוד. אלא – משתנים שיש להם משמעות ויזואלית , ז”א שינוי שלהם גורר שינוי בתצוגה או כפי שאמרנו, שינוי שיש בו תלות – ניצור משתנה מסוג state. משתנים אלו ריאקט שמה עליהם עין ובודקת שינויים. בכל שינוי – ריאקט מרנדרת את כל הקומפוננטות הרלוונטיות בעץ הקומפוננטות.
משתנה state מוגדר כך: const [user, setUser] = useState({name:””, address:””});
כשהערך שמקבל הuseState הוא הערך ההתחלתי של המשתנה.
בעצם, הפונקציה useState מחזירה מערך שמכיל במקום הראשון את הערך הראשוני שניתן לה, ובמקום השני פונקציה לעדכון הערך.
אין אפשרות לשנות את הערך ישירות, מכיוון שריאקט אחראית לניהולם ועדכונם של משתני סטייט. יש להשתמש בפונקציית עדכון הערך.
בכל פעם שריאקט מזהה שינוי של משתנה סטייט- היא מרנדרת את הקומפוננטה מחדש, עם הערך החדש.
useEffect:
Hooks
הוקס הם פונקציות שמאפשרות להשתמש בפיצרים רבים הקשורים לסטייט של הקומפוננטה ולמחזור החיים שלה, שהיו קיימים קודם רק במחלקות, בקומפוננטות מסוג פונקציה.
ריאקט מגדירה זאת כך:
” Hooks הם פונקציות שנותנות לך “להתחבר” ל-state של React ותכונות מחזור חיים מתוך קומפוננטות פונקציה.”
ההוק הראשון והשימושי ביותר הוא useState.
הוק נוסף הוא הuseEffect- הוק שמתייחס למחזור החיים של הקומפוננטה.
מה קורה כשמשתנה סטייט מתעדכן?
דיברנו על משתני סטייט ואמרנו שזהו משתנה שריאקט יודעת לסנכרן עם המסך ולשנות את המסך בכל המקומות שתלויים בערך שהשתנה.
איך בעצם זה עובד? איך ריאקט יודעת את מה היא צריכה לעדכן?
ריאקט שומרת לעצמה virtual dom – דום וירטואלי –עותק של כל הJS של האפליקציה שלנו.
בכל שינוי של משתנה סטייט – היא משנה בוירטואל דום את כל המקומות הרלוונטיים ואז עוברת אל הדום האמיתי ומרנדרת שוב את הקומפוננטה העליונה שהשתנתה, ואת כל הבנים שלה.
מה ריאקט מרוויחה מזה?
בעיקר מהירות. גישה לדום היא דבר יקר, ואנו משתדלים להמנע מכך כמה שיותר. לעומת זאת שינוי של משתנה בJS זו פעולה זולה ופשוטה. כאן ריאקט חוסכת גישה מיותרת אל הדום וניגשת רק למה שרלוונטי.
בעצם על כל שינוי של סטייט – כל הקומפוננטות הרלוונטיות מריצות שוב את פונקציית הrender שלהן, או במקרה של קומפוננטת פונקציה – הפונקציה מופעלת שוב. (App()).
לכל קומפוננטה יש מחזור חיים
היא נולדת כשמגדירים אותה,
במהלך חייה היא עוברת שינויי סטייט ובעקבות כך רנדורים מחודשים
ובסוף מתה.
אנחנו רוצים להתייחס למצב הקומפוננטה ולפי זה לעשות פעולות מסוימות.
המצבים שאמורים לעניין אותנו – הקומפוננטה נוצרת, או הקומפוננטה מתעדכנת, מסיבת שינוי סטייט.
למשל- מייד בהולדת הקומפוננטה נרצה לעשות קריאת שרת שתייבא את כל הנתונים הרלוונטיים.
או בשינוי של משתנה סטייט מסוים , נרצה לשמור את הנתון החדש בlocal storage.
חשוב לשים לב: הקומפוננטה תתרנדר שוב רק אחרי שהפונקציה מסיימת לרוץ. זוהי פעולה אסינכרונית שלעולם אינה עוצרת פעולה סינכרונית. אם אנחנו רוצים לעשות פעולה דווקא אחרי שהמשתנה סטייט מתעדכן, עם הערך החדש – בדיוק בשביל זה יש לנו את ההוק – useEffect
useEffect רצה בכל פעם שהקומפוננטה מתרנדרת.
משתמשים בה בעיקר כדי לעשות פעולות צדדיות (side effects) שקורות כתוצאה משינוי של משתני state.
-
הוקס לעולם לא נקראים בתוך תנאי
-
הוקס לעולם לא מוגדרים בתוך לולאה
הסיבה היא שהצורה שבה ריאקט מנהלת את משתני הסטייט שלה- היא צריכה לדעת כבר כשהקומפוננטה נוצרת אילו וכמה משתני סטייט קיימים. כנ”ל לגבי שאר ההוקים.
-
-
סליחה על החפירה…
אבל קצת הסתבכתי במשהו…
יש לי קומפוננטה All_products שמכילה קונטיינר- ששם אמורים להיות מוצגים כל המוצרים.
את המוצרים אני מייבאת מקובץ JS פשוט שיש שם מערך (זה פרויקט לוקלי)את התצוגה של כל המוצרים אני יוצרת ע”י map
{filterData.map((product) => (
<ProductCard key={product.id}
product={product}
onDelete={handleDeleteProduct}
/>))}
קצת מבולגן אז יש תמונה.
יש לי קומפוננטה שמייצגת מוצר יחיד:ProductCard
שהיא מאתחלת לי את הנתונים, ואת התצוגה לכל מוצר.אני צריכה לעשות לכל מוצר את הכפתורים האלו (מצורף תמונה 2)
שבעיגול האמצעי זה הכמות הנוכחית, ובצדדים זה להפחית ולהוסיף.
אני צריכה לעשות שכשילחצו על אחד הכפתורים המידע יתעדכן גם מידית בתצוגה (ע”י state מסתבר..) וגם במערך המקורי, שכשאני יעבור לעמוד עריכת מוצר אני אראה את הכמות העדכנית.
יש מישי שיודעת לעזור לי בענין?
תודה רבה!!!!
-
האמת שהסתדרתי….
לגבי השאלה הראשונה אני ממש נואשת…..
כשאני עוברת מטופס עדכון לטופס מוצר חדש (שזה בעצם אותו טופס, רק אם הוא מקבל אוביקט ריק זה טופס מוצר חדש ואם אוביקט מלא זה עדכון, כשהשדות מתמלאים בdefault value בנתונים שקיימים באוביקט) השדות לא מתנקים, רק אם אני עוברת קודם לדף הבית ואז למוצר חדש זה עובד.
זה כנראה בעיה כלשהי בuseRef.
מי שתוכל להעיף מבט בקוד מאד תשמח אותי😉
תודה רבה!
-
-
-
-
נראה לי שבמקרה שזה טופס יצירת חדש את פשוט צריכה לנקות את ה state בטעינה כי הוא עדיין שומר לך את הערך הקודם- לאתחל אותו בערך ריק
Log in to reply.