useId は、をクセシビγƒͺγƒ†γ‚£ε±žζ€§γ«ζΈ‘γ™γ“γ¨γŒγ§γγ‚‹δΈ€ζ„οΏ½? ID γ‚’η”Ÿζˆγ™γ‚‹γŸγ‚οΏ½? React フックです。

const id = useId()

γƒͺフゑレンス

useId()

γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?γƒˆγƒƒγƒ—γƒ¬γƒ™γƒ«γ§ useId を呼び出して、一意�? ID γ‚’η”Ÿζˆγ—γΎγ™γ€‚

import { useId } from 'react';

function PasswordField() {
const passwordHintId = useId();
// ...

さらに例を見る

εΌ•ζ•°

useId γ―εΌ•ζ•°γ‚’ε—γ‘ε–γ‚ŠγΎγ›γ‚“γ€‚

θΏ”γ‚Šε€€

useId は、特�?οΏ½οΏ½?γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆε†…γ§γ“οΏ½?η‰ΉοΏ½?οΏ½οΏ½? useId οΏ½?ε‘Όγ³ε‡Ίγ—γ«ι–’ι€£δ»˜γ‘γ‚‰γ‚ŒγŸγ€δΈ€ζ„οΏ½? ID ζ–‡ε­—εˆ—γ‚’θΏ”γ—γΎγ™γ€‚

注意点

  • useId γ―γƒ•γƒƒγ‚―γ§γ‚γ‚‹γŸγ‚γ€γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?γƒˆγƒƒγƒ—γƒ¬γƒ™γƒ«γΎγŸγ―η‹¬θ‡ͺοΏ½?フック内で�?γΏε‘Όγ³ε‡Ίγ™γ“γ¨γŒγ§γγΎγ™γ€‚γƒ«γƒΌγƒ—γΎγŸγ―ζ‘δ»Άεˆ†ε²ε†…γ§ε‘Όγ³ε‡Ίγ™γ“γ¨γ―γ§γγΎγ›γ‚“γ€‚γ‚‚γ—εΏ…θ¦γͺε ΄εˆγ―γ€ζ–°γ—γ„γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’δ½œζˆγ—γ€ηŠΆζ…‹γ‚’η§»ε‹•γ•γ›γ‚‹εΏ…θ¦γŒγ‚γ‚ŠγΎγ™γ€‚

  • useId を、γƒͺγ‚Ήγƒˆε†…οΏ½? key οΏ½?η”Ÿζˆγ«γ―δ½Ώη”¨γ—γͺいでください。key γ―γƒ‡γƒΌγ‚Ώγ‹γ‚‰η”Ÿζˆγ•γ‚Œγ‚‹εΏ…θ¦γŒγ‚γ‚ŠγΎγ™γ€‚


使用法

落とし穴

γƒͺγ‚Ήγƒˆε†…οΏ½? key γ‚’η”Ÿζˆγ™γ‚‹γŸγ‚γ« useId を呼び出さγͺいでください。key γ―γƒ‡γƒΌγ‚Ώγ‹γ‚‰η”Ÿζˆγ•γ‚Œγ‚‹εΏ…θ¦γŒγ‚γ‚ŠγΎγ™γ€‚

をクセシビγƒͺγƒ†γ‚£ε±žζ€§οΏ½?γŸγ‚οΏ½?一意�? ID οΏ½?η”Ÿζˆ

γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?γƒˆγƒƒγƒ—γƒ¬γƒ™γƒ«γ§ useId を呼び出して、一意�? ID γ‚’η”Ÿζˆγ—γΎγ™γ€‚

import { useId } from 'react';

function PasswordField() {
const passwordHintId = useId();
// ...

そ�?εΎŒγ€η”Ÿζˆγ•γ‚ŒγŸ ID をさまざまγͺε±žζ€§γ«ζΈ‘γ™γ“γ¨γŒγ§γγΎγ™γ€‚

<>
<input type="password" aria-describedby={passwordHintId} />
<p id={passwordHintId}>
</>

γ“γ‚ŒγŒγ©οΏ½?γ‚ˆγ†γͺε ΄εˆγ«ε½Ήη«‹γ€γ‹γ‚’γ€δΎ‹γ‚’ι€šγ—γ¦γΏγ¦γΏγΎγ—γ‚‡γ†γ€‚

aria-describedby οΏ½?γ‚ˆγ†γͺ HTML をクセシビγƒͺγƒ†γ‚£ε±žζ€§γ‚’δ½Ώη”¨γ™γ‚‹γ¨γ€2 ぀�?γ‚Ώγ‚°γŒη›ΈδΊ’γ«ι–’ι€£γ—γ¦γ„γ‚‹γ“γ¨γ‚’ζŒ‡οΏ½?οΏ½γ™γ‚‹γ“γ¨γŒγ§γγΎγ™γ€‚δΎ‹γˆγ°γ€ε…₯εŠ›γƒ•γ‚£γƒΌγƒ«γƒ‰οΏ½?γ‚ˆγ†γͺθ¦η΄ γŒγ€οΏ½?�落γͺど�?εˆ₯οΏ½?要素でθͺ¬ζ˜Žγ•γ‚Œγ¦γ„γ‚‹γ“γ¨γ‚’ζŒ‡οΏ½?οΏ½γ™γ‚‹γ“γ¨γŒγ§γγΎγ™γ€‚

ι€šεΈΈοΏ½? HTML では、欑�?γ‚ˆγ†γ«θ¨˜θΏ°γ—γΎγ™γ€‚

<label>
Password:
<input
type="password"
aria-describedby="password-hint"
/>
</label>
<p id="password-hint">
The password should contain at least 18 characters
</p>

γŸγ γ—γ€γ“οΏ½?γ‚ˆγ†γ« ID をハードコードすることは、React γ§γ―γŠγ™γ™γ‚γ§γγΎγ›γ‚“γ€‚γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ―γƒšγƒΌγ‚ΈδΈŠγ§θ€‡ζ•°ε›žγƒ¬γƒ³γƒ€γƒΌε―θƒ½γ§γ™γŒγ€ID γ―δΈ€ζ„γ§γ‚γ‚‹εΏ…θ¦γŒγ‚γ‚ŠγΎγ™οΌ ID をハードコードする�?ではγͺく、useId を使用して一意�? ID γ‚’η”Ÿζˆγ—γΎγ™γ€‚

import { useId } from 'react';

function PasswordField() {
const passwordHintId = useId();
return (
<>
<label>
Password:
<input
type="password"
aria-describedby={passwordHintId}
/>
</label>
<p id={passwordHintId}>
The password should contain at least 18 characters
</p>
</>
);
}

γ“γ‚Œγ§γ€η”»ι’δΈŠγ« PasswordField γŒθ€‡ζ•°ε›žθ‘¨η€Ίγ•γ‚Œγ‚‹ε ΄εˆγ§γ‚‚γ€η”Ÿζˆγ•γ‚Œγ‚‹ ID が同じにγͺγ‚‹γ“γ¨γ―γ‚γ‚ŠγΎγ›γ‚“γ€‚

import { useId } from 'react';

function PasswordField() {
  const passwordHintId = useId();
  return (
    <>
      <label>
        Password:
        <input
          type="password"
          aria-describedby={passwordHintId}
        />
      </label>
      <p id={passwordHintId}>
        The password should contain at least 18 characters
      </p>
    </>
  );
}

export default function App() {
  return (
    <>
      <h2>Choose password</h2>
      <PasswordField />
      <h2>Confirm password</h2>
      <PasswordField />
    </>
  );
}

こ�?ビデγ‚ͺγ‚’θ¦‹γ¦ζ”―ζ΄ζŠ€θ‘“γ«γ‚ˆγ‚‹γ€γƒ¦γƒΌγ‚Άδ½“ι¨“οΏ½?違いを璺θͺγ—てみてください。

落とし穴

ァーバレンダγƒͺングでは、useId γ«γ―γ‚΅γƒΌγƒγ¨γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆδΈŠγ§εŒδΈ€οΏ½?γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγƒ„γƒͺγƒΌγŒεΏ…θ¦γ§γ™γ€‚γ‚΅γƒΌγƒδΈŠγ¨γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆδΈŠγ§γƒ¬γƒ³γƒ€γƒΌγ•γ‚Œγ‚‹γƒ„γƒͺγƒΌγŒζ­£η’Ίγ«δΈ€θ‡΄γ—γͺγ„ε ΄εˆγ€η”Ÿζˆγ•γ‚Œγ‚‹ ID は一致しません。

さらに深くηŸ₯γ‚‹

useId γŒε’—εˆ†γ‚«γ‚¦γƒ³γ‚Ώγ‚ˆγ‚Šγ‚‚θ‰―γ„η†η”±

useId が nextId++ οΏ½?γ‚ˆγ†γͺγ‚°γƒ­γƒΌγƒγƒ«ε€‰ζ•°γ‚’ε’—εˆ†γ™γ‚‹γ‚ˆγ‚Šγ‚‚γͺγœθ‰―γ„οΏ½?γ‹γ€η–‘ε•γ«ζ€γ‚γ‚Œγ‚‹γ‹γ‚‚γ—γ‚ŒγΎγ›γ‚“γ€‚

useId οΏ½?δΈ»γͺεˆ©η‚Ήγ―γ€React γŒγ€γ‚΅γƒΌγƒγƒ¬γƒ³γƒ€γƒͺングで璺�?οΏ½γ«ζ©Ÿθƒ½γ™γ‚‹γ“γ¨γ‚’δΏθ¨Όγ—γ¦γ„γ‚‹γ“γ¨γ§γ™γ€‚γ‚΅γƒΌγƒγ§οΏ½?γƒ¬γƒ³γƒ€γƒΌδΈ­γ«γ€γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ― HTML 归式�?ε‡ΊεŠ›γ‚’η”Ÿζˆγ—γΎγ™γ€‚γοΏ½?εΎŒγ‚―γƒ©γ‚€γ‚’γƒ³γƒˆδΈŠγ§γ€η”Ÿζˆγ•γ‚ŒγŸ HTML γ«γ€γƒγ‚€γƒ‰γƒ¬γƒΌγ‚·γƒ§γƒ³γ«γ‚ˆγ£γ¦γ€γ‚€γƒ™γƒ³γƒˆγƒγƒ³γƒ‰γƒ©γŒγ‚’γ‚Ώγƒƒγƒγ•γ‚ŒγΎγ™γ€‚γƒγ‚€γƒ‰γƒ¬γƒΌγ‚·γƒ§γƒ³γŒζ©Ÿθƒ½γ™γ‚‹γ«γ―γ€γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆοΏ½?ε‡ΊεŠ›γŒγ‚΅γƒΌγƒοΏ½? HTML γ¨δΈ€θ‡΄γ™γ‚‹εΏ…θ¦γŒγ‚γ‚ŠγΎγ™γ€‚

γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγŒγƒγ‚€γƒ‰γƒ¬γƒΌγƒˆγ•γ‚Œγ‚‹ι †εΊγ―γ€γ‚΅γƒΌγƒ HTML γŒε‡ΊεŠ›γ•γ‚ŒγŸι †εΊγ¨δΈ€θ‡΄γ—γͺγ„ε―θƒ½ζ€§γŒγ‚γ‚‹γŸγ‚γ€γ“γ‚Œγ‚’γ‚€γƒ³γ‚―γƒͺγƒ‘γƒ³γƒˆγ‚«γ‚¦γƒ³γ‚Ώγ§δΏθ¨Όγ™γ‚‹γ“γ¨γ―ιžεΈΈγ«ε›°ι›£γ§γ™γ€‚useId γ‚’ε‘Όγ³ε‡Ίγ™γ“γ¨γ§γ€γƒγ‚€γƒ‰γƒ¬γƒΌγ‚·γƒ§γƒ³γŒζ©Ÿθƒ½γ—γ€γ‚΅γƒΌγƒγ¨γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆοΏ½?ι–“γ§ε‡ΊεŠ›γŒδΈ€θ‡΄γ™γ‚‹γ“γ¨γŒδΏθ¨Όγ•γ‚ŒγΎγ™γ€‚

React ε†…ιƒ¨γ§γ―γ€ε‘Όγ³ε‡Ίγ—ε…ƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½? β€œθ¦ͺοΏ½?パス (parent path)” から useId γŒη”Ÿζˆγ•γ‚ŒγΎγ™γ€‚γοΏ½?γŸγ‚γ€γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ¨γ‚΅γƒΌγƒοΏ½?ツγƒͺγƒΌγŒεŒγ˜γ§γ‚γ‚Œγ°γ€γƒ¬γƒ³γƒ€γƒΌι †εΊγ«ι–’δΏ‚γͺく β€œθ¦ͺοΏ½?パス” γŒδΈ€θ‡΄γ™γ‚‹γ“γ¨γ«γͺγ‚ŠγΎγ™γ€‚


耇数�?閒連要素に ID γ‚’δΈŽγˆγ‚‹εΏ…θ¦γŒγ‚γ‚‹ε ΄εˆγ―γ€useId γ§η”Ÿζˆγ—γŸε€€γ‚’ε…±ζœ‰οΏ½?プレフィックスとして使用できます。

import { useId } from 'react';

export default function Form() {
  const id = useId();
  return (
    <form>
      <label htmlFor={id + '-firstName'}>First Name:</label>
      <input id={id + '-firstName'} type="text" />
      <hr />
      <label htmlFor={id + '-lastName'}>Last Name:</label>
      <input id={id + '-lastName'} type="text" />
    </form>
  );
}

γ“γ‚Œγ«γ‚ˆγ‚Šγ€δΈ€ζ„οΏ½? ID を必要とするすべて�?要素に対して useId γ‚’ε‘Όγ³ε‡Ίγ™εΏ…θ¦γŒγͺくγͺγ‚ŠγΎγ™γ€‚


η”Ÿζˆγ•γ‚Œγ‚‹γ™γΉγ¦οΏ½? ID γ«ε…±ζœ‰γƒ—γƒ¬γƒ•γ‚£γƒƒγ‚―γ‚Ήγ‚’ζŒ‡οΏ½?�する

耇数�?η‹¬η«‹γ—γŸ React γ‚’γƒ—γƒͺケーションを 1 ぀�?γƒšγƒΌγ‚Έγ«γƒ¬γƒ³γƒ€γƒΌγ™γ‚‹ε ΄εˆγ―γ€γ‚ͺプションとして identifierPrefix γ‚’ createRoot または hydrateRoot γ«ζΈ‘γ—γΎγ™γ€‚γ“γ‚Œγ«γ‚ˆγ‚Šγ€useId γ§η”Ÿζˆγ•γ‚ŒγŸγ™γΉγ¦οΏ½?識εˆ₯ε­γŒζŒ‡οΏ½?οΏ½γ—γŸε€‹εˆ₯οΏ½?γƒ—γƒ¬γƒ•γ‚£γƒƒγ‚―γ‚Ήγ§ε§‹γΎγ‚‹γŸγ‚γ€2 ぀�?η•°γͺγ‚‹γ‚’γƒ—γƒͺγ«γ‚ˆγ£γ¦η”Ÿζˆγ•γ‚ŒγŸ ID が葝ηͺγ™γ‚‹γ“γ¨γŒγͺくγͺγ‚ŠγΎγ™γ€‚

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 />);