props הם הקלטים של קומפוננטת React. הורה מעביר אותם כמאפיינים ב-JSX, <UserCard name="Ada" online={true} />, והילד מקבל אותם כאובייקט אחד, שבדרך כלל עושים לו destructuring בפרמטרים של הפונקציה. props מאפשרים לקומפוננטה אחת להציג נתונים שונים בכל פעם שמשתמשים בה.
אותה UserCard מרנדרת שלושה אנשים שונים. שימו לב לאחרון: מאפיין בלי ערך, online, פירושו online={true}. הוסיפו כרטיס רביעי עם השם והתפקיד שלכם.
העברה וקריאה של props
מחרוזת מעבירים במירכאות וכל ערך אחר בסוגריים מסולסלים: מספרים, בוליאנים, מערכים, אובייקטים, פונקציות, ואפילו JSX.
<Product
title="Desk lamp"
price={39.5}
inStock={false}
tags={['light', 'office']}
seller={{ name: 'Lumen', rating: 4.8 }}
/>
React אוספת את כל המאפיינים לאובייקט אחד ומעבירה אותו כארגומנט הראשון של הקומפוננטה. אפשר לקרוא אותו בתור props, או לפרק את השדות שצריך ישר ברשימת הפרמטרים:
function Product(props) {
return <h3>{props.title}</h3>;
}
function Product({ title, price, seller }) {
return <h3>{title}, ${price} from {seller.name}</h3>;
}
שתי הגרסאות מקבלות את אותו אובייקט. destructuring הוא הסגנון הנפוץ, כי אז החתימה של הפונקציה מפרטת בדיוק באילו props הקומפוננטה משתמשת.
ערכי ברירת מחדל
תנו ל-prop ערך ברירת מחדל עם ברירת המחדל של destructuring ב-JavaScript, = value. היא חלה כשההורה לא מעביר את ה-prop, או מעביר undefined. היא לא חלה על null, 0, false או '', שהם ערכים אמיתיים.
שלושת הכפתורים הראשונים חוזרים לברירות המחדל שלהם כש-prop חסר או undefined. האחרון מעביר null, ולכן size באמת null, והחיפוש לא מוצא padding. שנו את size={null} ל-size="small" כדי לתקן.
קוד ישן קובע ברירות מחדל עם מאפיין סטטי, Button.defaultProps = { size: 'medium' }. React 19 הסירה את defaultProps מקומפוננטות פונקציה: JSX מתעלם ממנו בפונקציה, בלי אזהרה. הוא עדיין עובד בקומפוננטות class. השתמשו בברירות מחדל של destructuring.
העברת פונקציות כ-props
נתונים זורמים מטה: הורה מעביר props לילדים שלו, אף פעם לא להפך. כשילד צריך להודיע להורה שמשהו קרה, ההורה מעביר פונקציה, והילד קורא לה. לפי המוסכמה, ל-props כאלה קוראים onSomething.
Rating לא שומרת כלום. היא מציגה את ה-value שהיא מקבלת ומדווחת על לחיצות דרך onRate. ה-state נמצא ב-App, שמעבירה אותו בחזרה מטה. העבירו onRate={setRating} ישירות במקום handleRate וזה עדיין עובד: גם setter הוא פונקציה. העברת state להורה משותף בצורה כזו נקראת הרמת state למעלה.
spread ל-props
כשכבר יש לכם אובייקט שהמפתחות שלו תואמים ל-props של קומפוננטה, פרשו אותו עם {...object} במקום לכתוב כל מאפיין. תחביר ה-rest עושה את ההפך ברשימת הפרמטרים: לוקחים כמה props לפי שם, אוספים את כל השאר ומעבירים הלאה.
האווטאר השני עושה spread ל-person ואז קובע color: כשאותו prop מופיע פעמיים, האחרון מנצח, ולכן שימו את הדריסות אחרי ה-spread. TextField שומרת את label לעצמה ומעבירה את type, placeholder ו-maxLength ישר ל-<input>. השתמשו ב-spread לעטיפות כמו זו; במקומות אחרים, פירוט מפורש של ה-props מקל לראות מה קומפוננטה מקבלת.
props הם לקריאה בלבד
קומפוננטה לעולם לא צריכה לשנות את ה-props של עצמה. הם שייכים להורה, ואותו אובייקט עשוי להיות משותף. התייחסו אליהם כמו לארגומנטים של פונקציה שאסור לכם להציב להם ערך חדש:
function Counter({ count }) {
count = count + 1; // wrong: changes a local copy, the parent never sees it
return <p>{count}</p>;
}
function Profile(props) {
props.name = 'Someone else'; // wrong: in development React freezes props, so this throws a TypeError
return <p>{props.name}</p>;
}
props עדיין משתנים עם הזמן. כשההורה מתרנדר שוב עם ערכים חדשים, הילד מקבל אובייקט props חדש ומתרנדר איתו:
Temperature אף פעם לא משנה את celsius. היא מחשבת ממנו את fahrenheit בכל רינדור. גררו את הסליידר וה-state של ההורה משתנה, כך שהילד מקבל prop חדש. אם ילד צריך ערך שהוא יכול לשנות בעצמו, הערך הזה הוא state, לא prop.
props מול state
props ו-state הם שניהם ערכי JavaScript רגילים שמשפיעים על מה שקומפוננטה מרנדרת, ושינוי באחד מהם מרנדר את הקומפוננטה מחדש. ההבדל הוא למי שייך הערך.
| props | state | |
|---|---|---|
| מגיע מ | ההורה, כמאפייני JSX | הקומפוננטה עצמה, מ-useState או useReducer |
| האם הקומפוננטה יכולה לשנות אותו | לא, הוא לקריאה בלבד | כן, דרך ה-setter שלו |
| שימוש טיפוסי | הגדרת קומפוננטה: תווית, גודל, הנתונים להצגה | לזכור משהו שמשתנה: טקסט בשדה, תפריט פתוח |
לעיתים קרובות אותו ערך הוא שניהם. בדוגמת הטמפרטורה שלמעלה, celsius הוא state ב-App ו-prop ב-Temperature. הבעלים מחזיק אותו כ-state ומעביר אותו מטה כ-prop, יחד עם פונקציה לשנות אותו כשילד צריך את זה.
prop יכול להחזיק כל ערך, כולל JSX וקומפוננטות. העברת אלמנט כמו icon={<StarIcon />} מאפשרת להורה למלא "חריץ" בילד, אותו רעיון כמו children עם שם לבחירתכם.
ה-prop children
כל מה שמכניסים בין תגית הפתיחה לתגית הסגירה של קומפוננטה מגיע כ-prop בשם children. כך בונים עטיפות כמו כרטיסים, פאנלים ו-layouts שלא יודעים מראש מה התוכן שלהם:
הדף על children מכסה העברה של כמה חריצים ועבודה בטוחה עם children.
keys הם לא props
key נראה כמו מאפיין, אבל React שומרת אותו לעצמה כדי להתאים פריטי רשימה בין רינדורים. הקומפוננטה אף פעם לא מקבלת אותו:
הקונסול מציג את props.key כ-undefined ואת props.id עם הערך האמיתי. כשילד צריך את המזהה, העבירו אותו פעם שנייה בשם אחר, כמו id כאן. build של פיתוח גם מזהיר כשקוראים את props.key; התצוגה המקדימה רצה כמו build של פרודקשן, אז רואים רק את ה-undefined.
שאלות נפוצות
מה זה props ב-React?
props (קיצור של properties) הם הארגומנטים של קומפוננטה. הורה מעביר אותם כמאפייני JSX, <Avatar size={48} />, והילד מקבל אותם כאובייקט אחד, בדרך כלל עם destructuring: function Avatar({ size }).
איך קובעים ערך ברירת מחדל ל-prop?
משתמשים בברירת מחדל של destructuring: function Button({ size = 'medium' }). ברירת המחדל חלה כשה-prop חסר או undefined. React 19 הסירה את defaultProps מקומפוננטות פונקציה; קומפוננטות class עדיין תומכות בו.
קומפוננטת ילד יכולה לשנות את ה-props שלה?
לא. props הם לקריאה בלבד. כדי לשנות את מה שהילד מציג, ההורה מעביר props חדשים; כדי לאפשר לילד לבקש שינוי, ההורה מעביר פונקציה כמו onChange והילד קורא לה.
מה ההבדל בין props ל-state?
props מגיעים מההורה והילד לא יכול לשנות אותם. state שייך לקומפוננטה עצמה ומשתנה דרך ה-setter שלו. לעיתים קרובות ערך מסוים הוא state אצל ההורה ו-prop אצל הילדים שלו.
למה props.key הוא undefined?
key (כמו ref בגרסאות ישנות של React) משמש את React עצמה למעקב אחרי פריטי רשימה ולא מועבר לקומפוננטה. אם הילד צריך את הערך, העבירו אותו שוב בשם אחר, למשל <Row key={id} id={id} />.