useId
는 React 18 버전에 도입된 훅으로, 노드의 트리 위치를 나타내는 고유 ID(Base32 문자열)를 반환한다. 컴포넌트 트리가 여러 자식(children)으로 분기될 때마다 ID에 추가 비트를 삽입해서 각 자식의 위치를 나타낸다.
:r0: (부모 컴포넌트)
:r1: (자식 컴포넌트1)
:r2: (자식 컴포너트2)
...
주로 서버 / 클라이언트에서 생성한 트리(tree) 사이의 하이드레이션(hydration) 불일치(mismatch)를 방지하기 위해 사용한다. 즉, useId
가 생성한 고유한 ID를 이용해 원활한 하이드레이션을 돕는 목적인 것. 리스트의 key를 만들기 위한 목적이 아니므로 주의한다.
<aside>
<img src="/icons/search_gray.svg" alt="/icons/search_gray.svg" width="40px" /> :
(콜론)은 querySelector 같은 CSS 셀렉터에선 지원하지 않는다(\\
백슬래시로 이스케이프해서 사용할 수는 있다). useId는 :
토큰을 포함한 문자열을 생성하므로 CSS 셀렉터에선 사용할 수 없다.
</aside>
export default function App() {
const id = useId();
return (
<div>
<h3>{`App - ${id}`}</h3> {/* App - :r0: */}
<Child /> {/* Child - :r1: SubChild - :r2: */}
<Child /> {/* Child - :r3: SubChild - :r4: */}
</div>
);
} // App.js
export default function Child() {
const id = useId();
return (
<div>
<h3>{`Child - ${id}`}</h3>
<SubChild />
</div>
);
} // Child.js
export default function SubChild() {
const id = useId();
return <h3>{`SubChild - ${id}`}</h3>
} // SubChild.js
App - :r0:
Child - :r1:
SubChild - :r2:
Child - :r3:
SubChild - :r4:
참고로 동일 컴포넌트에서 useId
훅을 여러번 호출하면 각각 다른 ID를 생성한다.
// App.js
const id1 = useId();
const id2 = useId();
console.log(id1, id2) // :r0: :r1:
<label> ⇄ <input> 요소를 연결할 때 useId가 생성한
유니크 ID
를 활용할 수 있다.
function Checkbox() {
const id = useId();
return (
<>
<label htmlFor={id}>Do you like React?</label>
<input id={id} type="checkbox" name="react"/>
</>
);
};
여러 필드에 사용할 땐
유니크 ID + 접미사
방식으로 사용할 수도 있다.
function NameFields() {
const id = useId();
return (
<div>
<label htmlFor={id + '-firstName'}>First Name</label>
<div>
<input id={id + '-firstName'} type="text" />
</div>
<label htmlFor={id + '-lastName'}>Last Name</label>
<div>
<input id={id + '-lastName'} type="text" />
</div>
</div>
);
}