useId
, erişilebilirlik özniteliklerine iletmek üzere benzersiz kimlikler üreten React Hook’udur.
const id = useId()
Referans
useId()
Benzersiz bir kimlik oluşturmak için useId
’yi bileşeninizin en üst kapsamında çağırın:
import { useId } from 'react';
function PasswordField() {
const passwordHintId = useId();
// ...
Daha fazla örnek için aşağıya bakın.
Parametreler
Herhangi bir parametre almaz.
Dönüş değeri
Çağrıldığı bileşene özel olarak her bir useId
çağrısı için karakter dizisi (string) tipinde benzersiz kimlik döner.
Dikkat edilmesi gerekenler
-
useId
bir Hook olduğundan, yalnızca bileşeninizin en üst kapsamında ya da kendi Hook’larınızda çağırabilirsiniz. Döngülerin ve koşulların içinde çağıramazsınız. Eğer çağırmak zorunda kaldıysanız yeni bir bileşene çıkarın ve state’i ona taşıyın. -
Liste elemanlarına anahtar üretmek için kullanılmamalıdır. Anahtarlar elinizdeki veriden üretilmelidir.
Kullanım
Erişilebilirlik öznitelikleri için benzersiz kimlikler üretmek
Benzersiz kimlikler üretmek için bileşeninizin en üst kapsamında useId
’yi çağırın:
import { useId } from 'react';
function PasswordField() {
const passwordHintId = useId();
// ...
Daha sonra oluşturulan kimliği farklı özniteliklere iletebilirsiniz:
<>
<input type="password" aria-describedby={passwordHintId} />
<p id={passwordHintId}>
</>
Bunun ne zaman faydalı olabileceğini görmek için bir örnek üzerinden ilerleyelim.
aria-describedby
gibi HTML erişilebilirlik öznitelikleri, iki etiketin birbirine bağlı olduğunu belirtmenizi sağlar. Örneğin, bir elementin (mesela <input>
) başka bir element (mesela <p>
) tarafından tanımlandığını belirtebilirsiniz.
Saf HTML’de bunu şu şekilde yazarsınız:
<label>
Şifre:
<input
type="password"
aria-describedby="password-hint"
/>
</label>
<p id="password-hint">
Şifre en az 18 karakter içermelidir
</p>
Ancak, doğrudan koda yazılan kimlikler React’ta iyi bir pratik değildir. Bir bileşen sayfada birden fazla kez render edilebilir—ancak kimlikler benzersiz olmalıdır! Bunun yerine useId
ile benzersiz bir kimlik oluşturun:
import { useId } from 'react';
function PasswordField() {
const passwordHintId = useId();
return (
<>
<label>
Şifre:
<input
type="password"
aria-describedby={passwordHintId}
/>
</label>
<p id={passwordHintId}>
Şifre en az 18 karakter içermelidir
</p>
</>
);
}
Artık PasswordField
ekranda birden fazla kez görünse bile üretilen kimlikler çakışmaz.
import { useId } from 'react'; function PasswordField() { const passwordHintId = useId(); return ( <> <label> Şifre: <input type="password" aria-describedby={passwordHintId} /> </label> <p id={passwordHintId}> Şifre en az 18 karakter içermelidir </p> </> ); } export default function App() { return ( <> <h2>Şifreni seç</h2> <PasswordField /> <h2>Şifreni doğrula</h2> <PasswordField /> </> ); }
Yardımcı teknolojiler ile edinilen kullanıcı deneyiminde yarattığı farkı görmek için bu videoyu izleyin.
Derinlemesine İnceleme
useId
’nin nextId++
gibi global bir değişkeni arttırmaktan neden daha iyi olduğunu merak ediyor olabilirsiniz.
Temel avantajı, React’ın sunucu taraflı render ile çalışacağını garanti etmesidir. Bileşenleriniz sunucu taraflı render ensasında HTML çıktısı üretir. Ardından istemcide, üretilen HTML’e hidratlama (hydration) sırasında olay yöneticileri eklenir. Hidratlamanın çalışması için, istemci çıktısının sunucu HTML’iyle eşleşmesi gerekir.
Artan sayaç kullanarak bunu garanti etmek çok zordur. İstemci bileşenlerinin hidratlanma sırası ile sunucu HTML’inin tarayıcıya gönderilme sırası eşleşmeyebilir. useId
’yi çağırmak; hidratlamanın çalışacağından, sunucu ve istemci arasındaki çıktının özdeş olacağından emin olmanızı sağlar.
React’ta useId
’nin değeri, çağrıldığı bileşenin ağaç içindeki hiyerarşik yolundan (parent path) üretilir. Dolayısıyla sunucu ve istemci ağaçları aynıysa, ürettikleri değerler render sırasına bakılmaksızın eşleşecektir.
Birkaç ilişkili element için kimlik üretmek
Bir takım ilişkili elemente kimlik vermeniz gerekiyorsa, useId
’yi çağırarak ürettiğiniz kimliği sonekler ile özelleştirebilirsiniz:
import { useId } from 'react'; export default function Form() { const id = useId(); return ( <form> <label htmlFor={id + '-firstName'}>İsim:</label> <input id={id + '-firstName'} type="text" /> <hr /> <label htmlFor={id + '-lastName'}>Soyisim:</label> <input id={id + '-lastName'} type="text" /> </form> ); }
Bu kullanım, benzersiz kimliğe ihtiyaç duyan her bir element için useId
’yi çağırmaktan kaçınmanızı sağlar.
Üretilen tüm kimlikler için önek belirlemek
Tek bir sayfada birden fazla bağımsız React uygulaması render ederseniz, createRoot
veya hydrateRoot
metodlarına iletebileceğiniz identifierPrefix
parametresini kullanın. Bu sayede useId
ile oluşturulan her bir kimlik benzersiz bir önek ile başlayacağından, iki farklı uygulama tarafından oluşturulan kimlikler asla çakışmaz.
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 />);
Using the same ID prefix on the client and the server
If you render multiple independent React apps on the same page, and some of these apps are server-rendered, make sure that the identifierPrefix
you pass to the hydrateRoot
call on the client side is the same as the identifierPrefix
you pass to the server APIs such as renderToPipeableStream
.
// Server
import { renderToPipeableStream } from 'react-dom/server';
const { pipe } = renderToPipeableStream(
<App />,
{ identifierPrefix: 'react-app1' }
);
// Client
import { hydrateRoot } from 'react-dom/client';
const domNode = document.getElementById('root');
const root = hydrateRoot(
domNode,
reactNode,
{ identifierPrefix: 'react-app1' }
);
You do not need to pass identifierPrefix
if you only have one React app on the page.