ריאקט 18 סוף סוף מציע פיתרון לבעיית ה label-ים
עד שהגיע ריאקט או בכלל הרעיון של קומפוננטות, מתכנתים ומתכנתות כתבו קבצי HTML גדולים ובתוכם היו label-ים ו input-ים המתואמים ביניהם באמצעות id:
<label for="name">User Name</label>
<input type="text" id="name" />
ואז בא ריאקט ולימד אותנו שלא כדאי להשתמש ב id על אלמנטים כי אולי מישהו הולך להשתמש בקומפוננטה שלך בעוד כמה מקומות ואז יהיה במסמך id כפול. מפה מתכנתים ומתכנתות התחילו לחפש פיתרונות יצירתיים, החל מ:
<label>
User Name
<input type="text" />
</label>
ועד דברים יותר מתוחכמים כמו המצאת מזהים:
function MyForm() {
const id = Math.random().toString(16);
return (
<>
<label htmlFor={id}>User Name</label>
<input type="text" id={id} />
</>
);
}
הבעיה בפיתרון הראשון היא שהוא מכריח markup מסוים. כל עוד זה עובד לכם הכל טוב, אבל לפעמים באמת ה label וה input לא צמודים אחד לשני. הבעיה בפיתרון השני היא שכנראה לא נקבל את אותו id ב Server Side Rendering, מה שייצור אי תאימות כשריאקט יריץ את כל ה render-ים בדפדפן ויקבל HTML עם מזהים שונים.
ריאקט 18 סוף סוף מציעים פיתרון קל ונוח לבעיה עם הוק בשם useId
. פונקציה זו תחזיר מזהה ייחודי ותבטיח לכם שתקבלו את אותו מזהה ברינדור בצד שרת ובצד הלקוח. לכן הדרך הנכונה בריאקט 18 לכתוב את אותו קוד היא:
import { useId } from 'react';
function MyForm() {
const id = useId();
return (
<>
<label htmlFor={id}>User Name</label>
<input type="text" id={id} />
</>
);
}
ה id שמקבלים לא יצירתי במיוחד ובדוגמה שניסיתי קיבלתי מחרוזת כמו :r1:
, :r3
ו :r5:
. אני לא יודע למה דווקא r ולמה הוא מדלג על הזוגיים. אם יש לכם רעיון או מידע פנימי אשמח לשמוע בתגובות.