본문 바로가기

이것저것 스터디📚/React - 공식 문서

React 공식문서 -userId

- userId : 접근성 속성에 전달할 수 있는 고유 ID를 생성하기 위한 React 훅이다.

- useId는 특정 컴포넌트 내 특정 useId와 관련된 고유 ID 문자열을 반환한다.

- useId를 목록에서의 키 생성하기 위해 호출하지 말아야 한다. 키는 데이터에서 생성되어야 한다.

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

- ID를 하드코딩하는 것은 React에서 좋은 방법은 아니며, 컴포넌트는 페이지에서 두 번 이상 렌더링될 수 있지만, ID는 고유해야 한다.

- 위 예제에서 userId로 useId를 생성하고 있기 때문에, PasswordField가 화면에 여러번 나타나도 생성된 ID가 충돌되지 않는다.


Why is useId better than an incrementing counter?(중복 카운터보다 useId가 더 나은 이유는 무엇일까?)

- useId를 nextId++ 처럼 전역 변수를 증가시키는 것보다 더 나은 이유

- React가 서버 렌더링과 함께 동작하도록 보장한다

- 서버 렌더링 중에 컴포넌트는 HTML 출력을 생성하는데, 이후 클라이언트에서 hydration이 붙여진 이벤트 핸들러를 생성된 HTML에 연결한다.

- 클라이언트 컴포넌트가 hydration 되는 순서가 서버 HTML이 생성된 순서와 일치하지 않을 수 있기 때문에, 증가 카운터로는 이를 보장하기가 매우 어렵다.

- useId를 호출하면 hydration이 작동하고, 서버와 클라이언트의 출력물이 서로 일치하는지 확인할 수 있다.

- React 내부에서 useId는 호출한 컴포넌트의 "부모 경로"에서 생성되기 때문에, 클라이언트와 서버 트리가 동일하면 렌더링 순서와 상관없이 "부모 경로"가 일치하게 되므로 useId 역시 일치한다.


Generating IDs for several related elements(여러 관련 요소에 대한 ID 생성)

- 여러 관련 요소에 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>
  );
}

Specifying a shared prefix for all generated IDs(생성된 모든 ID에 공유 접두사 지정하기)

- 단일 페이지에서 여러 개의 독립적인 React 애플리케이션을 렌더링하는 경우, createRoot 또는 hydrateRoot를 호출하여 identifierPrefix에 옵션으로 전달하면 생성된 모든 식별자가 고유한 접두사로 시작하기 때문에 서로 다른 두 앱에서 생성된 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 />);

* 참고 : React 공식문서(https://react-ko.dev/learn)