14.1 useId란?14.1.1 useId 개념과 기본구조14.1.2 useId를 사용하는 이유14.1.3. useId 사용 시 주의할 점14.2 useId 실용 예제14.2.1. useId 기본 사용법14.2.2 (실습 1) 컴포넌트 재사용 시 다른 아이디 생성하기14.2.3 (실습 2) 한 컴포넌트 내에서 다른 아이디 생성하기
14.1 useId란?
14.1.1 useId 개념과 기본구조
useId란 브라우저에서 렌더링할 때 안정적으로 고유한 ID를 생성하기 위한 용도로써 React에 내장된 Hook입니다. HTML에서 ID는 style sheet에서 특정 style 선언을 가리키는 데 사용되며, JavaScript에서 특정 ID를 가진 요소에 접근하고 조작하는 데 사용됩니다. React에서도 클라이언트와 서버에서 모두 상호작용할 수 있는 HTML로 렌더링하고 있기 때문에, React 컴포넌트에서 사용하는 ID를 HTML로 연결하여 동일하게 사용하고 있습니다.
React에서 useId를 사용하기 위해서 다음 코드처럼 Hook을 가져오고, 사용할 값을 선언하게 됩니다.
import { useId } from "react";
const id = useId();
14.1.2 useId를 사용하는 이유
useId를 사용하는 이유는 useId를 통해 쉽게 견고한 ID를 생성할 수 있기 때문입니다. 또한 useId는 : 토큰을 포함하는 문자열을 생성하여 다음 ID의 특징을 보장하고 있습니다.
- 한 페이지에서 하나의 고유한 ID를 사용해야 합니다. 만약 한 문서 안에 동일한 ID 값을 포함한다면, 사용자가 원하는 방식대로 요소를 관리할 수 없게 됩니다. useId를 사용한다면 React에서 작성한 ID를 고유하게 가질 수 있도록 설정하게 됩니다.
- ID는 ID를 통해 사람이 읽을 수 있는 정보를 드러내지 않는 것을 권장합니다. 이는 보안과 관련하여 문제가 될 수 있습니다. useId로 ID를 생성한다면 해당 ID 요소의 정보와는 관련 없이 생성해주기 때문에 보안 문제를 해결할 수 있습니다.
- useId를 사용하면 재랜더링과 같은 다른 변화에도 일관성 있게 ID의 값을 유지할 수 있습니다.
14.1.3. useId 사용 시 주의할 점
useId를 사용할 때 몇 가지 주의해야할 상황에 대해 알아보도록 하겠습니다.
- useId는 루프 혹은 조건 내에서 호출이 불가능합니다. useId는 Hook이기 때문에 컴포넌트의 최상위 요소에서만 호출이 가능합니다.
- 생성된 ID는 CSS 선택자로 사용할 수 없습니다. useId를 이용해 ID를 생성하게 되면 문자열을 반환하지만
:r1:
,:r2:
처럼 콜론을 포함하는 값을 ID로 생성해 줍니다. CSS 선택자에서 특수문자를 포함하는 문자열을 지원하지 않기 때문에 CSS 선택자로 사용이 불가능합니다. 하지만 이런 경우, useId를 사용하여 원하는 요소에 접근할 수는 없지만 useRef를 사용하게되면 접근이 가능합니다.
- 매번 고유 ID를 생성해 주기 때문에 변경해서는 안 되는 값에는 사용하지 않아야 합니다. 따라서 목록의 key값을 생성하는 데에는 사용하지 않는 것이 좋습니다.
14.2 useId 실용 예제
useId를 이용하면 간단하게 고유의 ID를 생성할 수 있습니다. 이번 챕터에서는 useId를 사용하는 방법을 간단한 예제를 통해 알아보겠습니다.
14.2.1. useId 기본 사용법
App.jsx는 useId로 체크박스에 ID를 부여하고, Child 라는 컴포넌트를 보여주는 코드입니다.
import React, { useId } from 'react'; import Child from './Child'; function App() { const id = useId(); return ( <> <label htmlFor={id}>App check</label> <input type="checkbox" id={id} /> <Child /> <Child /> <Child /> </> ); } export default App;
Child 컴포넌트 또한 위와 같이 체크박스에 useId를 이용하여 아이디를 부여하는 코드입니다.
import React, { useId } from 'react'; function Child() { const id = useId(); return ( <> <br /> // 줄바꿈 위한 코드 <label htmlFor={id}>Child Check</label> <input type="checkbox" id={id} /> </> ); } export default Child;

해당 코드들의 ID값을 확인하기 위해 개발자도구를 확인하면, 같은 Child 컴포넌트의 코드이지만 이렇게 각각 다른 ID값이 생성되는 것을 확인할 수 있습니다.
이처럼 useId를 이용하면 같은 페이지에 컴포넌트가 여러번 렌더링 되더라도 일일이 다른 ID를 직접 넣지 않고 편리하게 고유한 ID값을 부여할 수 있습니다.
14.2.2 (실습 1) 컴포넌트 재사용 시 다른 아이디 생성하기
useId는 input 요소와 label을 연결하는 등 HTML 요소를 연결할 때 useId를 사용할 수 있습니다.
function NameForm() { return ( <> <label htmlFor="name">이름</label> <input id="name" type="text" /> </> ); } function App() { return ( <> <NameForm /> <NameForm /> <NameForm /> </> ); } export default App;

위의 코드는 문제없이 잘 작동합니다. 하지만 같은 페이지에서 위의 컴포넌트를 여러 번 렌더링하는 경우 동일한 ID를 가진 여러 개의 입력 요소를 가지게 됩니다. 페이지의 모든 ID는 고유한 ID를 가져야 하며, 3번째 input의 label을 클릭하더라도 해당 label과 연결된 input 요소 대신 첫 번째 input 요소에 focus가 맞춰지기 때문에 좋은 방법이라고 할 수는 없습니다. 이와 같은 문제를 해결하기 위해 useId를 사용할 수 있습니다.
import { useId } from 'react' function NameForm() { const id = useId(); return ( <> <label htmlFor={id}>이름</label> <input id={id} type="text" /> </> ); } function App() { return ( <> <NameForm /> <NameForm /> <NameForm /> </> ); } export default App;

이처럼 useId를 통해 ID를 생성하게 되면 같은 페이지에서 컴포넌트가 여러 번 렌더링 되더라도 고유한 ID 값을 가지게 되기 때문에 중복 ID에 대한 걱정 없이 원하는 만큼 컴포넌트를 렌더링 할 수 있습니다.
14.2.3 (실습 2) 한 컴포넌트 내에서 다른 아이디 생성하기
import { useId } from 'react' function App() { const id = useId(); return ( <div> <label htmlFor={id + '-nickname'}> 닉네임 </label> <div> <input id={id + '-nickname'} type="text" /> </div> <label htmlFor={id + '-password'}> 비밀번호 </label> <div> <input id={id + '-password'} type="password" /> </div> </div> ); } export default App;
위 예제에서 보시는 것과 같이 useId를 사용하여 전역적으로 서버와 클라이언트 모두 동일하게 사용할 수 있는 ID를 만들 수 있습니다.
그리고 n개의 서로 다른 ID를 만들기 위해 useId를 여러번 사용하여 생성하는 대신 하나의 useId를 만들어 고유한 동적인 ID를 만들고 접미사를 붙여 서로 다른 아이디를 만들 수 있습니다.
현재 예제에서 닉네임과 비밀번호 두 개의 입력창을 만들기 위해는 각각 다른 ID가 필요합니다. 이때 useId를 사용하여 id라는 변수를 만들고 ‘-nickname’과 ‘-password’라는 접미사를 붙여 서로 다른 ID를 생성했습니다.


위 예제를 실행하면 다음과 같이 렌더링됩니다.
id + '-nickname'
은 :r0: -nickname
으로 렌더링되고 id + '-password'
는 :r0: -password
로 렌더링되었습니다. 이처럼 같은 useId로 생성한 ID를 사용하더라도 접미사를 붙이면 서로 다른 ID로 생성된다는 것을 확인할 수 있습니다.