React 고급 Hook (React 18+)
1. useId (서버와 클라이언트에서 동일한 ID 생성)
- React 18+에서 추가된 고유한 ID를 생성하는 Hook.
- 클라이언트와 서버에서 같은 ID를 유지하도록 설계됨.
- SSR(서버 사이드 렌더링) 환경에서 ID 충돌 방지.
폼 라벨 연결
import { useId } from "react";
const Example = () => {
const id = useId(); // 고유한 ID 생성
return (
<div>
<label htmlFor={id}>이름:</label>
<input id={id} type="text" />
</div>
);
};
export default Example;
id가 자동으로 생성되므로, 여러 개의 <input> 요소를 사용해도 충돌이 발생하지 않음.
SSR(Next.js 등)에서 클라이언트와 서버의 ID가 일치하도록 보장함.
2. useDeferredValue (값 업데이트 지연 처리)
- 입력 필드 등의 값이 빠르게 변할 때 불필요한 렌더링을 줄이고 성능을 최적화.
- 입력값은 즉시 반영되지만, 연산이 무거운 작업은 지연됨.
입력 필드 최적화
import { useState, useDeferredValue } from "react";
const Example = () => {
const [text, setText] = useState("");
const deferredText = useDeferredValue(text); // 입력값을 지연 처리
return (
<div>
<input value={text} onChange={(e) => setText(e.target.value)} />
<p>즉시 반영: {text}</p>
<p>지연된 반영: {deferredText}</p>
</div>
);
};
export default Example;
사용자가 입력하는 텍스트는 즉시 반영되지만, 지연된 값(deferredText)은 일정 시간 후 업데이트됨.
리스트 검색 등의 UI에서 불필요한 렌더링을 줄이는 데 유용함.
3. useTransition (UI가 멈추지 않게 백그라운드에서 처리)
- 상태 업데이트를 낮은 우선순위로 실행하여 사용자가 입력하는 동안 UI가 멈추지 않도록 함.
- 긴 연산이 필요할 때 렌더링을 백그라운드에서 실행.
리스트 필터링 최적화
import { useState, useTransition } from "react";
const Example = () => {
const [text, setText] = useState("");
const [list, setList] = useState([]);
const [isPending, startTransition] = useTransition();
const handleChange = (e) => {
setText(e.target.value);
startTransition(() => {
setList(Array(10000).fill(e.target.value)); // 무거운 연산 실행
});
};
return (
<div>
<input value={text} onChange={handleChange} />
{isPending && <p>로딩 중...</p>}
<ul>{list.map((item, index) => <li key={index}>{item}</li>)}</ul>
</div>
);
};
export default Example;
사용자가 입력하는 동안 UI가 멈추지 않음.
리스트 업데이트는 백그라운드에서 실행되어 성능 최적화가 가능함.
4. useSyncExternalStore (외부 상태 구독)
- Redux, Zustand 같은 상태 관리 라이브러리와 함께 사용하기 위해 React 18에서 도입됨.
- 상태 저장소를 **구독(subscribe)**하여 변경 사항을 감지하고 반영함.
Zustand와 함께 사용
import { useSyncExternalStore } from "react";
import { create } from "zustand";
// Zustand 상태 저장소
const useStore = create((set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
}));
const Example = () => {
const count = useSyncExternalStore(useStore.subscribe, useStore.getState().count);
return (
<div>
<h1>카운트: {count}</h1>
<button onClick={useStore.getState().increase}>증가</button>
</div>
);
};
export default Example;
외부 상태를 직접 구독(subscribe)하여 React 상태와 동기화할 수 있음.
Redux 등 기존 상태 관리 라이브러리의 connect()보다 더 성능이 최적화됨.
5. useDebugValue (React DevTools에서 디버깅용)
- 커스텀 Hook의 값을 React DevTools에서 디버깅할 때 사용.
- 디버깅 목적 이외에는 필요하지 않음.
커스텀 Hook 디버깅
import { useDebugValue, useState } from "react";
const useCounter = () => {
const [count, setCount] = useState(0);
useDebugValue(count > 5 ? "많음" : "적음"); // React DevTools에서 표시됨
return { count, setCount };
};
const Example = () => {
const { count, setCount } = useCounter();
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
};
export default Example;
React DevTools에서 useDebugValue 값을 확인할 수 있음.
커스텀 Hook을 사용할 때, 디버깅이 더 쉬워짐.
6. useErrorBoundary (실험적 Hook - 오류 경계)
- 컴포넌트 내부에서 발생한 오류를 감지하여 UI에서 처리할 수 있도록 함.
- React의 Error Boundary(오류 경계)를 Hook 형태로 사용할 수 있음.
오류 감지 및 복구
import { useState } from "react";
import { useErrorBoundary } from "react-error-boundary"; // 실험적 라이브러리
const ErrorComponent = () => {
const [count, setCount] = useState(0);
if (count === 5) {
throw new Error("오류 발생!"); // 오류 발생
}
return <button onClick={() => setCount(count + 1)}>클릭: {count}</button>;
};
const App = () => {
const { resetBoundary } = useErrorBoundary(); // 오류 리셋 기능 제공
return (
<div>
<h1>오류 경계 예제</h1>
<ErrorComponent />
<button onClick={resetBoundary}>오류 초기화</button>
</div>
);
};
export default App;
컴포넌트에서 발생한 오류를 감지하고 UI에서 처리할 수 있음.
resetBoundary를 사용하면 오류 상태를 초기화할 수 있음.
'JavaScript > React' 카테고리의 다른 글
| .env 파일과 실행 모드 (1) | 2025.03.28 |
|---|---|
| Jest와 React Test Library(RTL) (0) | 2025.03.25 |
| useRef, useImperativeHandle (1) | 2025.03.21 |
| useEffect, useLayoutEffect, useInsertionEffect (0) | 2025.03.21 |
| React Router DOM (0) | 2025.03.21 |