עיבוד מותנה
הרכיבים שלך יצטרכו לעתים קרובות להציג דברים שונים בהתאם לתנאים שונים. ב-React, אתה יכול לעבד JSX באופן מותנה באמצעות תחביר JavaScript כמו if statements, && ו? : אופרטורים.
You will learn
- כיצד להחזיר JSX שונה בהתאם לתנאי
- כיצד לכלול או לא לכלול חלק של JSX באופן מותנה
- קיצורי דרך תחביר מותנים נפוצים שתתקלו בבסיסי קוד React
החזרת JSX על תנאי
נניח שיש לך רכיב PackingList המציג מספר Items, שניתן לסמן כארוז או לא:
function Item({ name, isPacked }) { return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
שימו לב שלחלק מהרכיבים Item יש isPacked אבזר שלהם מוגדר ל-true במקום false. אתה רוצה להוסיף סימן ביקורת (✔) לפריטים ארוזים אם isPacked={true}.
אתה יכול לכתוב את זה בתור if/else statement כך:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;אם הפריט isPacked הוא true, הקוד הזה מחזיר עץ JSX אחר. עם השינוי הזה, חלק מהפריטים מקבלים סימן ביקורת בסוף:
function Item({ name, isPacked }) { if (isPacked) { return <li className="item">{name} ✔</li>; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
נסה לערוך את מה שמוחזר בכל מקרה, וראה כיצד התוצאה משתנה!
שימו לב כיצד אתם יוצרים לוגיקה מסועפת עם if ו-return state של JavaScript. ב-React, זרימת הבקרה (כמו תנאים) מטופלת על ידי JavaScript.
לא מחזיר דבר על תנאי עם null
במצבים מסוימים, לא תרצה לרנדר שום דבר בכלל. לדוגמה, תגיד שאתה לא רוצה להציג פריטים ארוזים בכלל. רכיב חייב להחזיר משהו. במקרה זה, תוכל להחזיר את null:
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;אם isPacked נכון, הרכיב לא יחזיר דבר, null. אחרת, הוא יחזיר את JSX לעיבוד.
function Item({ name, isPacked }) { if (isPacked) { return null; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
בפועל, החזרת null מרכיב אינה נפוצה מכיוון שuse היא עשויה להפתיע מפתח שמנסה לרנדר אותו. לעתים קרובות יותר, תכלול או לא תכלול את הרכיב ב-JSX של רכיב האב. הנה איך לעשות את זה!
כולל JSX באופן מותנה
בדוגמה הקודמת, שלטת איזה (אם בכלל!) עץ JSX יוחזר על ידי הרכיב. ייתכן שכבר שמת לב לשכפול מסוים בפלט העיבוד:
<li className="item">{name} ✔</li>דומה מאוד ל
<li className="item">{name}</li>שני הענפים המותנים מחזירים <li className="item">...</li>:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;אמנם שכפול זה אינו מזיק, אך הוא עלול להקשות על תחזוקת הקוד שלך. מה אם אתה רוצה לשנות את ה-className? תצטרך לעשות זאת בשני מקומות בקוד שלך! במצב כזה, אתה יכול לכלול מעט JSX כדי להפוך את הקוד שלך ליותר יבש.
אופרטור מותנה (שלישי) (? :)
ל-JavaScript יש תחביר קומפקטי לכתיבת ביטוי מותנה — האופרטור המותנה](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) או “אופרטור טרירי”.
במקום זה:
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;אתה יכול לכתוב את זה:
return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);אתה יכול לקרוא את זה בתור “אם isPacked הוא אמיתי, אז (?) render name + ' ✔', אחרת (:) render name”.
Deep Dive
אם אתה מגיע מרקע תכנות מונחה עצמים, אתה עשוי להניח ששתי הדוגמאות שלמעלה שונות בתכלית מכיוון שuse אחת מהן עשויה ליצור שני “מופעים” שונים של <li>. אבל אלמנטים JSX אינם “מופעים” מכיוון שuse הם אינם מכילים שום state פנימי ואינם צמתים DOM אמיתיים. הם תיאורים קלים, כמו שרטוטים. כך ששתי הדוגמאות הללו, למעשה, שוות לחלוטין. מצב שימור ואיפוס מפרט כיצד זה עובד.
כעת נניח שאתה רוצה לעטוף את הטקסט של הפריט שהושלם בתג HTML אחר, כמו <del> כדי למחוק אותו. אתה יכול להוסיף עוד שורות חדשות וסוגריים כדי שיהיה קל יותר לקנן עוד JSX בכל אחד מהמקרים:
function Item({ name, isPacked }) { return ( <li className="item"> {isPacked ? ( <del> {name + ' ✔'} </del> ) : ( name )} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
סגנון זה עובד היטב עבור תנאים פשוטים, אבל use אותו במידה. אם הרכיבים שלך מבולגנים עם יותר מדי סימון מותנה מקונן, שקול לחלץ רכיבי צאצא כדי לנקות דברים. ב-React, סימון הוא חלק מהקוד שלך, אז אתה יכול use כלים כמו משתנים ופונקציות כדי לסדר ביטויים מורכבים.
אופרטור AND לוגי (&&)
קיצור דרך נפוץ נוסף שתתקל בו הוא האופרטור JavaScript לוגי AND (&&). בתוך רכיבי React, הוא מופיע לעתים קרובות כאשר אתה רוצה לעבד כמה JSX כשהתנאי נכון, או לעבד שום דבר אחרת. עם https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND#:~:text=The%20logical%20AND%20(%20%26%26%20)%20operator,it%20returns%20a%20Boolean%20value.) ברכיבי React, אתה יכול לסמן את התנאי K2 רק_1__ true:
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);אתה יכול לקרוא את זה בתור “אם isPacked, אז (&&) עבד את סימן הביקורת, אחרת, לא עבד כלום”.
הנה זה בפעולה:
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
ביטוי JavaScript && מחזיר את הערך של הצד הימני שלו (במקרה שלנו, סימן הביקורת) אם הצד השמאלי (המצב שלנו) הוא true. אבל אם התנאי הוא false, הביטוי כולו הופך לfalse. React מחשיב את __TK__3 כמו __TK__3 בעץ, בדיוק כמו __TK__3 null או undefined, ואינו מעבד שום דבר במקומו.
הקצאה מותנית של JSX למשתנה
כאשר קיצורי הדרך מפריעים לכתיבת קוד רגיל, נסה להשתמש ב-if statement ובמשתנה. אתה יכול להקצות מחדש משתנים שהוגדרו באמצעות let, אז התחל על ידי מתן תוכן ברירת המחדל שברצונך להציג, השם:
let itemContent = name;השתמש ב-if statement כדי להקצות מחדש ביטוי JSX ל-itemContent אם isPacked הוא true:
if (isPacked) {
itemContent = name + " ✔";
}סוגריים מתולתלים פותחים את “החלון אל JavaScript”. הטמע את המשתנה עם סוגרים מתולתלים בסוג JSX שהוחזר בתוך העץ __K_2 שחושב קודם לכן ב-__K: __K
<li className="item">
{itemContent}
</li>סגנון זה הוא המלל ביותר, אך הוא גם הגמיש ביותר. הנה זה בפעולה:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = name + " ✔"; } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
כמו קודם, זה עובד לא רק עבור טקסט, אלא גם עבור JSX שרירותי:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = ( <del> {name + " ✔"} </del> ); } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
אם אינך מכיר את JavaScript, מגוון הסגנונות הזה עשוי להיראות מהמם בהתחלה. עם זאת, לימוד אותם יעזור לך לקרוא ולכתוב כל קוד JavaScript — ולא רק רכיבי React! בחר את זה שאתה מעדיף בתור התחלה, ולאחר מכן עיין בהפניה זו שוב אם אתה שוכח איך האחרים עובדים.
Recap
- ב-React, אתה שולט בלוגיקת הסתעפות עם JavaScript.
- אתה יכול להחזיר ביטוי JSX באופן מותנה עם
ifstatement. - אתה יכול לשמור כמה JSX במשתנה ואז לכלול אותו בתוך JSX אחר על ידי שימוש בסוגריים המתולתלים.
- ב-JSX,
{cond ? <A /> : <B />}פירושו “אםcond, עיבוד<A />, אחרת<B />”. - ב-JSX,
{cond && <A />}פירושו “אםcond, render<A />, אחרת כלום”. - קיצורי הדרך נפוצים, אבל אתה לא צריך use אותם אם אתה מעדיף
ifרגיל.
Challenge 1 of 3: הצג סמל עבור פריטים לא שלמים עם ? :
השתמש באופרטור המותנה (cond ? a : b) כדי להציג ❌ אם isPacked אינו true.
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✔'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }