טיפ טעינת תמונות בריאקט עם ובלי מפתח

20/05/2024

הקומפוננטה הבאה מציגה 4 כפתורים כל כפתור טוען תמונה אחרת באזור המרכזי של המסך:

function App() {
  const [image, setImage] = React.useState(0);
  return (
    <div>
      <div>
        <button onClick={() => setImage(0)}>1</button>
        <button onClick={() => setImage(1)}>2</button>
        <button onClick={() => setImage(2)}>3</button>
        <button onClick={() => setImage(3)}>4</button>
      </div>
      <img src={images[image]} />
    </div>
  )
}

ככה זה נראה לייב בקודפן:

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

מה קורה פה?

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

איך מתקנים?

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

function App() {
  const [image, setImage] = React.useState(0);
  return (
    <div>
      <div>
        <button onClick={() => setImage(0)}>1</button>
        <button onClick={() => setImage(1)}>2</button>
        <button onClick={() => setImage(2)}>3</button>
        <button onClick={() => setImage(3)}>4</button>
      </div>
      <img key={image} src={images[image]} />
    </div>
  )
}

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