רשימות ומפתחות
ראשית, בואו נסקור איך לשנות רשימות ב-JavaScript.
בהתחשב בקוד שלהלן, אנחנו משתמשים בפונקציית ()map
כדי לקחת מערך של מספרים numbers
ולהכפיל את הערכים שלהם. אנו מקצים את המערך החדש שחוזר מ-map()
למשתנה doubled
ומדפיסים אותו.
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);console.log(doubled);
הקוד הזה ידפיס [2, 4, 6, 8, 10]
לקונסול.
ב-React שינוי מערכים לרשימות של אלמנטים הוא כמעט זהה.
רינדור קומפוננטות מרובות
אתה יכול לבנות אוסף של אלמנטים ולכלול אותם ב-JSX באמצעות סוגריים מסולסלים {}
.
למטה, אנו רצים על numbers
מערך המספרים באמצעות פונקציית ()map
ב-JavaScript. אנו מחזירים <li>
אלמנט לכל פריט. לבסוף, אנו מקצים את המערך החוזר ל-listItems
:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => <li>{number}</li>);
<<<<<<< HEAD
אנו מכלילים את המערך listItems
כולו לתוך אלמנט <ul>
, ומרדנדרים את ה-DOM.
=======
Then, we can include the entire listItems
array inside a <ul>
element:
84ad3308338e2bb819f4f24fa8e9dfeeffaa970b
<ul>{listItems}</ul>
הקוד הזה מציג רשימה של מספרים מ-1 עד 5.
קומפוננטת רשימה בסיסית
בדרך כלל אנו נרנדר רשימה בתוך קומפוננטה.
אנחנו יכולים לשכתב את הדוגמה הקודמת לקומפוננטה שמקבלת numbers
מערך של מספרים ומדפיסה רשימה של אלמנטים.
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) => <li>{number}</li> ); return (
<ul>{listItems}</ul> );
}
const numbers = [1, 2, 3, 4, 5];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<NumberList numbers={numbers} />);
כאשר תריץ את הקוד הזה, תופיע אזהרה שמפתח צריך להיות מסופק לפריטים ברשימה. “מפתח” הוא תכונה מיוחדת מסוג מחרוזת שאתה צריך להכליל מתי שאתה יוצר רשימה של אלמנטים. נדון מדוע זה חשוב בחלק הבא.
בואו נקצה key
לרשימת הפריטים שלנו בתוך numbers.map()
ונתקן את בעיית חסרון המפתח.
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}> {number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
מפתחות
מפתחות עוזרים ל-React לזהות אילו פריטים השתנו, נוספו או נמחקו. מפתחות אמורים להינתן לאלמנטים בתוך המערך כדי לתת לאלמנטים זהות קבועה:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}> {number}
</li>
);
הדרך הטובה ביותר לבחור מפתח היא להשתמש במחרוזת שמזהה באופן ייחודי פריט מהרשימה בין אחיו. לרוב תבחר ID מהנתונים שלך כמפתח:
const todoItems = todos.map((todo) =>
<li key={todo.id}> {todo.text}
</li>
);
כאשר אין לך ID קבוע לרנדור הפריטים, אתה רשאי להשתמש באינדקס של האיבר כמפתח בתור מוצא אחרון:
const todoItems = todos.map((todo, index) =>
// קבוע ID עשה זאת אך ורק אם לפריט אין <li key={index}> {todo.text}
</li>
);
אנחנו לא ממליצים להשתמש באינדקסים עבור מפתחות אם סדר הפריטים ישתנה. זה יכול להשפיע לרעה על הביצועים ולגרום לבעיות ב-state של הקומפוננטה. עיין במאמר של Robin Pokorny בשביל הסבר מעמיק על ההשפעות השליליות של שימוש באינדקס כמפתח. אם תבחר לא להקצות מפתח מפורש לפריט ברשימה אז React ישתמש כברירת מחדל באינדקס כמפתח.
הנה הסבר מעמיק על למה מפתחות נחוצים אם אתה מעוניין ללמוד יותר.
חילוץ קומפוננטות עם מפתחות
מפתחות הגיוניים רק בהקשר של מערכים.
לדוגמה, אם אתה מחלץ קומפוננטת ListItem
, אתה תעדיף לשמור את המפתח באלמנט <ListItem />
שבמערך מאשר באלמנט <li>
שב-ListItem
עצמו.
דוגמה: שימוש לא נכון במפתח
function ListItem(props) {
const value = props.value;
return (
// טעות! אין צורך לציין את המפתח כאן <li key={value.toString()}> {value}
</li>
);
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// טעות! אתה צריך לציין את המפתח כאן <ListItem value={number} /> );
return (
<ul>
{listItems}
</ul>
);
}
דוגמה: שימוש נכון במפתח
function ListItem(props) {
// נכון! אין צורך לציין את המפתח כאן return <li>{props.value}</li>;}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// נכון! יש לציין את המפתח בתוך המערך <ListItem key={number.toString()} value={number} /> );
return (
<ul>
{listItems}
</ul>
);
}
כלל אצבע טוב הוא שאלמנטים בתוך map()
צריכים מפתחות.
מפתחות חייבים להיות ייחודיים בין אחים.
מפתחות חייבים להיות ייחודיים בין אחים. למרות זאת הם לא צריכים להיות ייחודיים באופן גלובאלי. אנחנו יכולים להשתמש באותם מפתחות כאשר אנו מייצרים שני מערכים שונים.
function Blog(props) {
const sidebar = ( <ul>
{props.posts.map((post) =>
<li key={post.id}> {post.title}
</li>
)}
</ul>
);
const content = props.posts.map((post) => <div key={post.id}> <h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);
return (
<div>
{sidebar} <hr />
{content} </div>
);
}
const posts = [
{id: 1, title: 'שלום עולם', content: '!React ברוכים הבאים ללמידת'},
{id: 2, title: 'התקנה', content: 'npm-מ React אתה יכול להתקין את'}
];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Blog posts={posts} />);
מפתחות משרתים כרמז ל-React אבל הם אינם עוברים לקומפוננטות שלך. אם אתה צריך את אותו הערך בקומפוננטה שלך, העבר אותו בצורה מפורשת כ-prop עם שם אחר.
const content = posts.map((post) =>
<Post
key={post.id} id={post.id} title={post.title} />
);
עם הדוגמה למטה, קומפוננטת Post
יכולה לקרוא את props.id
אבל לא את props.key
.
הטמעת ()map בתוך JSX
בדוגמאות למעלה הצהרנו על משתנה נפרד listItems
וכללנו אותו ב-JSX:
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) => <ListItem key={number.toString()} value={number} /> ); return (
<ul>
{listItems}
</ul>
);
}
JSX מאפשר להטמיע כל ביטוי בסוגריים מסולסלים כדי שנוכל להטביע את תוצאת map()
:
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) => <ListItem key={number.toString()} value={number} /> )} </ul>
);
}
לפעמים התוצאה היא קוד ברור יותר, אבל סגנון זה יכול להיות גם לרעה. כמו ב-JavaScript, זה תלוי בהחלטתך האם כדאי לחלץ משתנה למען שיפור קריאתו. זכור כי אם גוף פונקציית map()
יותר מידי מקונן, זה יכול להיות זמן טוב לחלץ קומפוננטה.