הצוות של ריאקט שחרר לנו את Context API בגרסה 16.3.0, החל מגרסא זו והלאה בטוח להשתמש ב- Context API אשר היה בשלבים ניסיוניים.
Context API מאפשר לנו דרך קלה לשיתוף נתונים גלובליים בכל עץ האתר. יכולת זו פותרת בעיה נפוצה המכונה- prop drilling, זהו מצב שבו props צריכים להיות מועברים אל מספר קומפוננטות בעץ כדי להגיע לקומפוננטה שבאמת צריכה את זה. דבר הגורם להעברת ״מידע״(Props) מיותר לקומפוננטות שלא צריכות את המידע.
בנוסף נוכל לשתף נתונים גם בין קומפוננטות שלא מקושרות אך עדיין צריכות לקבל מידע זהה למשל: שפת האתר.
במקרים רבים, זה יאפשר לנו להימנע משימוש בספריות צד שלישי כגון Redux ו-mobx, אשר היו מנהלות לנו את ה- Store.
מתי להשתמש ב- Context API?
כפי שציינו קודם, Context API שימושי לשיתוף נתונים שיכולים להיחשב גלובליים, כגון נתוני משתמש לאחר אוטנתיקציה,נתוני עגלת הקניות, הגדרות ערכת העיצוב, שפת האתר ועוד. במצבים אלו, אנו יכולים להשתמש ב- Context API , ואנחנו לא צריכים להשתמש בספריות נוספות.
אחרי שהבנו מהם השימושים של Context API ומה הוא בא לפתור בואו נראה איך נעשה השימוש בו.
תחילת עבודה עם Context API
כדי להתחיל לעבוד עם Context APi ניצור Context חדש באמצעות React.createContext.
לאחר שניצור את ה context נוכל לייצא ממנו את ה- Provider (הקומפוננטה שמספקת את הערך). ולהעביר לה את הstate שיצרנו כפרופס לערך value.
ה- Provider תמיד צריך לעטוף מסביבו את ה-parent, לא משנה איך נבחר לצרוך את הערכים מתוך ה- context. בדוגמא שלנו נעטוף את כל האפליקציה ב- provider ככה תהיה לנו גישה מכל הקומפוננטות בפרוייקט.
מתוך context נוכל לייצר גם את ה- consumer (הקומפוננטה שצורכת את הערך).
הדרך שבה נייצר את ה- provider זהה לקומפוננטות מסוג קלאסים ופונקציות אך צריכת המידע היא קצת שונה ביניהן.
ככל הנראה שמעתם על הוקס, אם לא אז הגיע הזמן 🙂
בואו נראה איך נשתמש בהוקס עם context APi כדי לקבל מידע.
כדי לצרוך את המידע בקומפוננטות מסוג קלאס אנו נעטוף את הקומפוננטה ב Consumer, לאחר שנעשה את זה נוכל לקבל גישה לכל המידע דרך props. יכול להשמע קצת מסובך אבל זה באמת פשוט, בואו נראה דוגמא
חדי העין ישימו לב שכל המידע זמין לנו רק בתוך ה- render. אז השאלה המתבקשת היא מה עם lifecycle methods?
אנו יכולים לעשות זאת בקומפוננטה מסוג קלאס עם contextType, שהוא משתנה סטטי בקלאס
שינוי מידע ב- Context
עד כה ראינו איך לייצר context עם ערך נתון ואיך אנחנו יכולים לגשת לערך זה מקומפוננטות שונות. אך ישנם מקרים בהם נרצה לשנות את הערך שהגדרנו או אפילו שהערך ההתחלתי הוא ריק ונרצה לחכות לדטא שיגיע מפנייה לשרת ולעשות השמה לאותו ערך. אז איך נעשה את זה? בדוגמא הבאה ניצור כפתור שישנה את הערך של המשתנה theme ל- dark.
תחילה נרשום פונקציה שמקבלת משתנה ומשנה את הערך של theme(כמובן שאם יש רק שתי ערכים יכלנו לעשות פונקציה של toggle אך נצא מנקודת הנחה שיש יותר משתי מצבים). ולאחר מכן נעביר אותה בvalue שמועבר ל-Context.Provider
לאחר שהגדרנו את הפונקציה ומה היא תעשה כעת נקרא לה מתוך הקומפוננטה, ניצור כפתור שיקרא לפונקציה changeTheme מתוך context.
לסיכום
- תחילה ניצור Context חדש באמצעת ()const xContext = React.createContext
- לאחר מכן נייבא מתוך context את ה- Provider ואת ה- Consumer
- נעטוף את האפליקציה שלנו ב Provider
- נצרוך את המידע שאנו צריכים באמצעות consumer
אם אהבתם את המאמר אשמח אם תשתפו/תמליצו לאחרים, אם יש לכם שאלות או הערות תוכלו להשאיר אותם בתגובות מתחת.
היה Context הרבה לפני 16.3.0… הם פשוט שכתבו אותו.
הוא לא מהווה תחליף ל-Redux ולא צריך להשתמש בו יותר מדי – הוא רלוונטי אך ורק למידע גלובאלי שצריך לצרוך ב*הרבה* Components ברמות שונות. אם תסתמך עליו יותר מדי בפרויקט, ה-Components שלך יהיו ספציפיים מדי ולא פתוחים ל-resuse. אם הבעיה היחידה היא העברת props ל-children עדיף להשתמש ב-Composition:
https://reactjs.org/docs/composition-vs-inheritance.html
https://reactjs.org/docs/context.html
אכן היה context לפני אך הוא היה בשלבי ניסוי..הוא השתנה קצת ושוחרר רשמית בגרסא 16.3
context יכול להיות תחליף לניהול State גלובאלי ובאמת לשמירת מידע שהרבה קומפוננטות משתמשות בו
אני מפתחת יחידה לפרויקט מאפס (העבודה הראשונה שלי בפיתוח)
השאלה תכלס במה להשתמש כאשר אני במסך login והמידע של המשתמש צריך להיות בכל במערכת
במה עדיף להשתמש
בredux או contex api
היי רחלי. זאת עבודה ראשונה שלך ואין אף אחד מעלייך שיכול להכווין או לעשות ריוויו לקוד?
מכיוון שאני לא יודע מה עתיד להיות גודל הפרוייקט אישית הייתי מתחיל בלי שום state managment אלא עם פרופס.
אם בהמשך תראי שאת צריכה אחד מהם אז הייתי בודק את mobx
תודה רבה על המאמר 🙂
שאלה – שינוי הvalue של הprovider דרך הקומפוננטה Home גורם לרינדור מחדש שלה?
אחרת איך ה themeColor ישתנה?
בנוסף, למה לנהל את הvalue עם state, אם אפשר לשמור אותו באובייקט רגיל?