למד הקשר להגיב בחמש דקות - מדריך למתחילים

ממשק ה- API של ההקשר של React הפך לכלי ניהול המדינה הנבחר עבור רבים, ולעתים קרובות מחליף את Redux לחלוטין. במדריך מהיר זה בן 5 דקות, תראה מבוא מהו הקשר וכיצד להשתמש בו!

אם אתה רוצה היכרות מתאימה לנושא זה, תוכל להצטרף לרשימת ההמתנה לקורס ה- React המתקדם הקרוב, או אם אתה עדיין מתחיל, עיין בקורס ההיכרות החינמי שלי בנושא React.

שקול עץ זה, שבו התיבות התחתונות מייצגות רכיבים נפרדים:

עץ רכיב

אנו יכולים להוסיף בקלות מצב לרכיבים התחתונים, אך עד כה הדרך היחידה להעביר נתונים לאחיו של רכיב הייתה להעביר את המצב לרכיב גבוה יותר ואז להעביר אותו חזרה לאח באמצעות אביזרים.

העברת נתונים באמצעות אביזרים

אם נגלה אחר כך שאחיו של הרכיב עם המדינה זקוק גם לנתונים, עלינו להרים את המצב שוב ולהעביר אותו בחזרה למטה:

העברת המדינה דרך מספר רמות

אמנם פתרון זה אכן עובד, אך הבעיות מתחילות אם רכיב בענף אחר זקוק לנתונים:

רכיב רחוק יותר דורש נתונים

במקרה זה, עלינו להעביר מצב מהרמה העליונה של היישום דרך כל מרכיבי הביניים לזה שזקוק לנתונים בתחתית, למרות שרמות הביניים אינן זקוקות לכך. תהליך מייגע וגוזל זמן זה מכונה קידוח אביזרים .

קידוח נכס

כאן נכנס Context API. הוא מספק דרך להעביר נתונים דרך עץ הרכיב דרך צמד ספקים-צרכנים מבלי להעביר אביזרים בכל רמה. תחשוב על זה כעל הרכיבים שמשחקים Catch with data - ייתכן ורכיבי המתווך לא "יודעים" שמשהו קורה:

הקשר בפעולה

כדי להדגים זאת, ניצור את תמונת המעבר הפנקית (והשימושית במיוחד) הזו מהלילה.

אם אתה רוצה לראות את הקוד המלא, הקפד לבדוק את מגרש המשחקים Scrimba עבור מאמר זה.

צור הקשר

כדי להתחיל, אנו יוצרים הקשר חדש. מכיוון שאנחנו רוצים שלכל האפליקציה תהיה גישה לכך, אנחנו הולכים index.jsועוטפים את האפליקציה ThemeContext.Provider.

אנו מעבירים גם את valueהאביזר לספק שלנו. זה מכיל את הנתונים שאנחנו רוצים לשמור. לעת עתה, אנחנו פשוט מקשיחים 'Day'.

import React from "react"; import ReactDOM from "react-dom"; import ThemeContext from "./themeContext"; import App from "./App"; ReactDOM.render(   , document.getElementById("root") ); 

צריכת הקשר עם contextType

נכון לעכשיו, ב App.js, אנחנו פשוט מחזירים את הרכיב.

import React from "react"; import Image from "./Image"; class App extends React.Component { render() { return ( ); } } export default App; 

המטרה שלנו היא להשתמש Context להחליף את classNames ב Image.jsמ Dayל Night, תלוי באיזה דמות שאנחנו רוצים להבהיר. לשם כך, אנו מוסיפים רכיב סטטי לרכיב שנקרא ContextTypeואז משתמשים באינטרפולציה מחרוזת כדי להוסיף אותו ל- classNames ברכיב.

כעת, classNames מכילים את המחרוזת valueמהאביזר. הערה: עברתי ThemeContextלקובץ משלו כדי למנוע באג.

import React from "react"; import Button from "./Button"; import ThemeContext from "./themeContext"; class Image extends React.Component { render() { const theme = this.context; return ( ); } } Image.contextType = ThemeContext; export default Image; 

הקשר. צרכנים

למרבה הצער, גישה זו עובדת רק עם רכיבים מבוססי כיתות. אם כבר למדת על הוקס ב- React, תדע שנוכל לעשות כמעט כל דבר עם רכיבים פונקציונליים בימינו. אז למען האמת, עלינו להמיר את הרכיבים שלנו לרכיבים פונקציונליים ואז להשתמש ThemeContext.Consumerברכיב כדי להעביר מידע דרך האפליקציה.

זה נעשה על ידי גלישת האלמנטים שלנו במופע של ובתוך זה (לאן childrenללכת), מתן פונקציה המחזירה את האלמנטים. זה משתמש בתבנית "render prop" שבו אנו מספקים פונקציה קבועה כילד שמחזיר איזשהו JSX לעיבוד.

import React from "react"; import Button from "./Button"; import ThemeContext from "./themeContext"; function Image(props) { // We don't need this anymore // const theme = this.context return (  {theme => ( )}  ); } // We don't need this anymore // Image.contextType = ThemeContext; export default Image; 

הערה: עלינו גם לעטוף את הרכיב - זה מאפשר לנו להוסיף פונקציונליות לכפתור בהמשך.

import React from "react"; import ThemeContext from "./themeContext"; function Button(props) { return (  {context => (  Switch  ?   ?   )}  ); } export default Button; 

חלץ ספק הקשר

כרגע אנו מעבירים ערך מקודד קשה דרך הספק, אולם מטרתנו היא לעבור בין לילה ליום באמצעות הכפתור שלנו.

לשם כך נדרש להעביר את הספק שלנו לקובץ נפרד ולהכניס אותו לרכיב משלו, במקרה זה, שנקרא ThemeContextProvider.

import React, { Component } from "react"; const { Provider, Consumer } = React.createContext(); class ThemeContextProvider extends Component { render() { return {this.props.children}; } } export { ThemeContextProvider, Consumer as ThemeContextConsumer }; 

הערה: מאפיין הערך מטופל כעת בקובץ החדש ThemeContext.js, ולכן יש להסירו מ- index.js.

שינוי הקשר

כדי לחבר את הכפתור, אנו מוסיפים תחילה מצב ל ThemeContextProvider:

import React, { Component } from "react"; const { Provider, Consumer } = React.createContext(); // Note: You could also use hooks to provide state and convert this into a functional component. class ThemeContextProvider extends Component { state = { theme: "Day" }; render() { return {this.props.children}; } } export { ThemeContextProvider, Consumer as ThemeContextConsumer }; 

לאחר מכן, אנו מוסיפים שיטה למעבר בין יום ללילה:

toggleTheme = () => { this.setState(prevState => { return { theme: prevState.theme === "Day" ? "Night" : "Day" }; }); }; 

כעת אנו משנים את valueהנכס שלנו this.state.themeכך שיחזיר את המידע מהמצב.

 render() { return {this.props.children}; } } 

לאחר מכן, אנו עוברים valueלאובייקט המכיל {theme: this.state.theme, toggleTheme: this.toggleTheme}, ומעדכנים את כל המקומות בהם אנו משתמשים בערך יחיד לחיפוש themeבאובייקט. המשמעות היא שכל themeהופך contextוכל התייחסות themeלערך הופכת להיות context.theme.

לבסוף, אנו אומרים לכפתור להקשיב onClickלאירוע ואז לירות context.toggleTheme- זה מעדכן את הצרכנים המשתמשים במדינה מהספק. הקוד של הכפתור נראה כך:

import React from "react"; import { ThemeContextConsumer } from "./themeContext"; function Button(props) { return (  {context => (  Switch  ?   ?   )}  ); } export default Button; 

הכפתור שלנו מחליף כעת את התמונה בין לילה ליום בלחיצה אחת!

אזהרות הקשר

כמו כל הדברים הטובים בקוד, יש כמה אזהרות לשימוש בהקשר:

  • אל תשתמש בהקשר כדי להימנע מקידוח אביזרים בשכבה אחת או שתיים בלבד. ההקשר נהדר לניהול מדינה אשר דרושה חלקים גדולים של יישום. עם זאת, קידוח אביזרים מהיר יותר אם אתה רק מעביר מידע בכמה שכבות.

  • הימנע משימוש בהקשר כדי לשמור מצב שיש לשמור עליו באופן מקומי. אז אם אתה צריך לשמור את קלטי הטופס של המשתמש, למשל, השתמש במצב מקומי ולא בהקשר.

  • תמיד עוטף את הספק סביב ההורה המשותף הנמוך ביותר האפשרי בעץ - לא הרכיב ברמה הגבוהה ביותר של האפליקציה. אין צורך בעודף.

  • לבסוף, אם אתה מעביר אובייקט כאביזר הערך שלך, עקוב אחר הביצועים והפקטור לפי הצורך. זה כנראה לא יהיה צורך אלא אם כן ניתן יהיה להבחין בירידה בביצועים.

לעטוף

דוגמה זו היא די פשוטה וכנראה שיהיה קל יותר להכניס מדינה לאפליקציה ולהעביר אותה באמצעות אביזרים. עם זאת, אני מקווה שמראה את העוצמה שיש לצרכנים שיכולים לגשת לנתונים ללא תלות ברכיבים שמעליהם בעץ.

למידע נוסף על Context Context ותכונות נהדרות אחרות של React, תוכל להצטרף לרשימת ההמתנה לקורס React המתקדם הקרוב. או אם אתם מחפשים ידידותי למתחילים יותר, תוכלו לבדוק את קורס ההיכרות החינמי שלי בנושא React.

קידוד שמח :)