
const id = useId()
useId는 각 컴포넌트마다 고유한 Id를 만들 때 사용하는 훅이다.
아무런 인자도 전달 받지 않는다.
// UseIdHook.js
function UseIdHook() {
return (
<div>
<MyInput />
<MyInput />
<br />
<InputProfile />
</div>
);
}
// MyInput.js
function MyInput() {
const id = useId();
return (
<div>
<label htmlFor={id}>이름</label>
<input id={id} />
<label htmlFor={id}>이름</label>
<input id={id} />
</div>
);
}
// InputProfile.js
function InputProfile() {
const profileId = useId();
return (
<div>
<label htmlFor={`${profileId}-name`}>이름</label>
<input id={`${profileId}-name`} />
<br />
<label htmlFor={`${profileId}-age`}>나이</label>
<input id={`${profileId}-age`} />
</div>
);
}
export default UseIdHook;
위 예제는 useId의 사용법과 포커싱을 관련 확인하기 위한 예제이다.
MyInput.js 에서 useId는 각 label과 input에 각 캄퍼넌트 별로 고유한 아이디를 적용해준다.
하나의 상수로 복사된 같은 컴포넌트에 고유한 Id를 분류할 수 있는 기능을 보여준다.
즉, 한 컴포넌트에서 사용되는 고유한 아이디를 만들어준다.
(htmlFor에 input의 아이디를 적어 연결할 수 있다.)
만약 한 컴포넌트에서 useId를 통해 생성된 아이디를 구분 시켜 줘야 한다면 InputProfile.js의 id처럼 백틱을 활용해 해당 객체를 설명하는 문자열을 포함시키면 된다.
useId의 장점은 아이디의 생김새다.
console을 찍어보면 :r0: 이런식으로 나온다.
요소의 아이디에 쌍점이 들어가있으면 querySelector 같은 동작들이 잘 작동하지 않는다(에러가 뜸). ref라는 기능이 있기 때문에 굳이 querySelector를 혼용하여 사용할 필요가 없게 해준다.
두번째 장점은 안정성이다.
기존에 랜덤한 id를 부여해주는 Math.random()과 같은 함수는 렌더링할 때 마다 다시 초기화가 된다. 그렇게 되면 from요소의 아이디도 계속해서 바뀌기 때문에 스크린리더를 사용하는 사람이 혼동을 느낄 수 있다.
하지만 useId로 만든 id는 렌더링이 발생되어도 유지된다. 그래서 훨씬 안정적이다.
서버사이드렌더링에서도 안정성을 보여준다.
(서버사이드렌더링 : 페이지를 서버에서 렌더링 후 클라이언트에게 전달. 클라이언트에게 전달된 페이지는 하이드레이션이란 과정을 통해 상호작용이 가능한 페이지로 렌더링 한다.)
클라이언트에게 전달된 페이지와 서버에서 제공해준 페이지 요소의 id가 일치하지 않아 문제가 발생하기도 한다.
useId는 서버와 클라이언트에서 모두 동일한 id를 생성되기 때문에 안정적으로 상호작용이 가능하다.
객체나 컴포넌트에 접근하기 위한 네이밍에 활용할 때 편한기능이다. 보다 정리된 코딩을 할 수 있을 것 같다.
또 새롭게 알게된게 스크린리더 사용자들을 위한 배려로 웹상에서도 베리어프리가 이루어진다는 것이 신선했다.