리액트 공식 문서를 참고한 정리 내용 (25.08 기준)
접근성 어튜리뷰에 전달할 수 있는 고유 ID를 생성하기 위한 Hook이다.
const id = useId()
useId를 컴포넌트의 최상위에서 호출하여 고유 ID를 생성한다.
import { useId } from 'react';
function PasswordField() {
const passwordHintId = useId();
// ...
useId는 어떤 매개변수도 받지 않는다
useId를 호출한 특정 컴포넌트와 특정 useId에 관련된 고유 ID 문자열을 반환한다.
useId는 리스트의 key를 생성하기 위해 사용하면 안된다useId는 비동기 서버 컴포넌트에서는 사용할 수 없다.서버 렌더링(SSR)에서는 서버에서 HTML을 만들고, 클라이언트가 그 HTML을 이어받아(hydration) 이벤트를 붙이는 과정이 있다.
이때 서버에서 만든 HTML과 클라이언트에서 만든 HTML과 클라이언트에서 만든 HTML이 100% 똑같아야 제대로 동작한다.
그런데 말입니다. 단순히 nextId++ 같이 전역 카운터로 ID를 만들면,
같은 페이지에 React 앱이 여러 개 올라갈 수 있는데, 이때 각 앱이 생성하는 useId 값이 서버와 클라이언트에서 달라지면 문제가 생긴다. 왜냐하면 hydration(서버에서 만든 HTML과 클라이언트를 이어붙이는 과정)에서는 ID가 반드시 동일해야 하기 때문!
이 문제를 해결하기 위해 React에서 제공하는 identifierPrefix라는 옵션을 사용한다.
renderToPipeableStream을 호출할 때 identifierPrefix: 'react-app1' 같이 지정hydrateRoot 호출 시 같은 identifierPrefix를 지정👉 이렇게 하면 서버와 클라이언트가 같은 규칙으로 ID를 만들기 때문에 충돌이 발생하지 않는다.
// server
const { pipe } = renderToPipeableStream(<App />, {
identifierPrefix: 'react-app1'
});
// client
const root = hydrateRoot(domNode, reactNode, {
identifierPrefix: 'react-app1'
});
👉 요약하자면,identifierPrefix는 서버와 클라이언트가 같은 ID를 쓰도록 맞춰주는 옵션이고, 여러 React 앱을 같은 페이지에 띄울 때 꼭 필요하다.