useId
useId
هو خطاف react يستخدم لإنشاء معرفات فريدة يمكن تمريرها إلى سمات إمكانية الوصول.
const id = useId()
المرجع
useId()
استدع useId
في المستوى الأعلى لمكونك لإنشاء معرف فريد
import { useId } from 'react';
function PasswordField() {
const passwordHintId = useId();
// ...
يرجى الإطلاع على المزيد من الأمثلة بالأسفل.
المعاملات (parameters)
useId
لا يقبل أي معاملات.
العائدات
useId
يعيد نص فريد مرتبط باستدعاء useId
المستخدم في هذا المكون تحديدا.
تنبيهات
-
useId
هو خطاف، لذلك يمكنك استدعائه فقط في المستوي الأعلي من مكونك أو من خلال الخطاطيف الخاصة بك. لا يمكنك استدعاء الخطاف داخل الحلقات والشروط. إذا كنت بحاجة إلي ذلك، قم بإستخراج مكون جديد وقم بنقل الحالة إليه. -
useId
لا ينبغي استخدامه لتوليد المفاتيح في القائمة. يجب أن تتم إنشاء المفاتيح من البيانات الخاصة بك.
الاستخدام
إنشاء معرفات فريدة لسمات إمكانية الوصول
استدعِ useId
في المستوي الأعلي من المكون الخاص بك لإنشاء معرف فريد:
import { useId } from 'react';
function PasswordField() {
const passwordHintId = useId();
// ...
يمكنك بعد ذلك تمرير المعرف الذى تم إنشاؤه إلى سمات مختلفة:
<>
<input type="password" aria-describedby={passwordHintId} />
<p id={passwordHintId}>
</>
دعنا نستعرض مثالا لمعرفة متى يكون ذلك مفيدا.
HTML accessibility attributes مثل aria-describedby
تتيح لك تحديد أن هناك علامتين مرتبطين ببعضهما البعض. على سبيل المثال، يمكنك تحديد أن العنصر (مثل صندوق الإدخال) يتم وصفه بواسطة عنصر آخر (مثل فقرة).
في HTML العادي ستكتبه بهذا الشكل:
<label>
Password:
<input
type="password"
aria-describedby="password-hint"
/>
</label>
<p id="password-hint">
يجب أن تحتوي كلمة السر على 18 حرفًا على الأقل
</p>
مع ذلك، تضمين المعرفات بهذا الشكل ليس طريقة جيدة في React. يمكن أن يتم عرض المكون أكثر من مرة على الصفحة، ولكن يجب أن تكون المعرفات فريدة! بدلا من تضمين معرف ثابت، يمكنك توليد معرف فريد باستخدام useId
:
import { useId } from 'react';
function PasswordField() {
const passwordHintId = useId();
return (
<>
<label>
Password:
<input
type="password"
aria-describedby={passwordHintId}
/>
</label>
<p id={passwordHintId}>
يجب أن تحتوي كلمة السر على 18 حرفًا على الأقل
</p>
</>
);
}
الآن، حتى إذا كان PasswordField
يظهر عدة مرات على الشاشة، لن تحدث تعارضات بين المعرفات المولدة.
import { useId } from 'react'; function PasswordField() { const passwordHintId = useId(); return ( <> <label> Password: <input type="password" aria-describedby={passwordHintId} /> </label> <p id={passwordHintId}> يجب أن تحتوي كلمة السر على 18 حرفًا على الأقل </p> </> ); } export default function App() { return ( <> <h2>أدخل كلمة سر</h2> <PasswordField /> <h2>تأكيد كلمة السر</h2> <PasswordField /> </> ); }
شاهد هذا الفيديو لترى الفرق في تجربة المستخدم مع تقنيات المساعدة.
Deep Dive
قد تتساءل لماذا useId
أفضل من زيادة متغير عالمي مثل nextId++
.
الفائدة الأساسية لـ useId
هي أن React ستضمن أنه يعمل مع تصيير الخادم. أثناء تصيير الخادم، يتم تحويل مكوناتك إلي عناصر HTML. في وقت لاحق، على العميل، hydration يقوم بربط معالجات الأحداث الخاصة بك بعناصر HTML التي تم توليدها. لكي يعمل تحويل العناصر على العميل بشكل صحيح، يجب أن يتطابق إخراج العميل مع HTML الذي على الخادم.
من الصعب جدا ضمان ذلك باستخدام عداد متزايد لأن ترتيب تحويل المكونات على العميل قد لا يتطابق مع ترتيب إخراج HTML على الخادم. من خلال استدعاء useId
، ستضمن أن عملية تحويل المكونات ستعمل بشكل صحيح، وسيتطابق الإخراج بين الخادم والعميل.
داخل React، يتم إنشاء useId
من الـ “مسار الأب” للمكون الذي يستدعيه. وهذا هو السبب في أنه إذا كانت شجرة العميل وشجرة الخادم متطابقتين، سيتطابق “مسار لأب” بغض النظر عن ترتيب العرض.
توليد معرفات لعدة عناصر ذات صلة
إذا كنت بحاجة إلى تعيين معرفات لعدة عناصر ذات صلة، يمكنك استدعاء useId
لتوليد بادئة مشتركة لها:
import { useId } from 'react'; export default function Form() { const id = useId(); return ( <form> <label htmlFor={id + '-firstName'}>الاسم الأول:</label> <input id={id + '-firstName'} type="text" /> <hr /> <label htmlFor={id + '-lastName'}>الاسم الأخير:</label> <input id={id + '-lastName'} type="text" /> </form> ); }
هذا يتيح لك تجنب استدعاء useId
لكل عنصر يحتاج إلى معرف فريد.
تحديد بادئة مشتركة لجميع المعرفات المولدة
إذا كنت تقوم بعرض عدة تطبيقات react مستقلة على صفحة واحدة, قم بتمرير identifierPrefix
كخيار إلى استدعاءات createRoot
أو hydrateRoot
الخاصة بك. هذا يضمن عدم حدوث تعارض بين المعرفات المولدة بواسطة التطبيقين المختلفين لأن كل معرف تم إنشاؤه باستخدام useId
سيبدأ بالبادئة المميزة التي حددتها.
import { createRoot } from 'react-dom/client'; import App from './App.js'; import './styles.css'; const root1 createRoot(document.getElementById('root1'), { identifierPrefix: 'my-first-app-' }); root1.render(<App />); const root2 = createRoot(document.getElementById('root2'), { identifierPrefix: 'my-second-app-' }); root2.render(<App />);