1. 프로젝트 개요
프론트엔드를 담당하면서 React 18, TypeScript, React Query, Hooks를 활용하여 개발을 진행했다. 이 과정에서 겪은 문제들과 해결 과정, 그리고 효율적인 컴포넌트 설계에 대해 공유하고자 한다.
2. 기술 개요
2.1 React 18 개요
React 18은 동시성 렌더링(Concurrent Rendering)과 자동 배치(Automatic Batching) 등의 새로운 기능을 추가하여 성능을 향상시킨 버전이다. 주요 기능은 다음과 같다:
- Concurrent Rendering: UI 업데이트를 더욱 부드럽게 처리할 수 있도록 함
- Automatic Batching: 여러 상태 업데이트를 자동으로 배치하여 불필요한 렌더링 방지
- Transition API: UI 상태 전환을 더욱 자연스럽게 제어 가능
2.2 TypeScript 개요
TypeScript는 JavaScript에 정적 타입을 추가한 언어로, 코드 안정성과 유지보수성을 높인다. 주요 특징은 다음과 같다:
- 정적 타입 검사: 컴파일 시 타입 오류를 감지하여 코드 안정성 향상
- 인터페이스와 타입 시스템: 복잡한 데이터 구조를 효과적으로 정의 가능
- IDE 지원 강화: 자동 완성과 코드 리팩토링이 쉬워짐
2.3 React Hooks 개요
React Hooks는 클래스형 컴포넌트 없이도 상태와 생명주기 기능을 사용할 수 있도록 하는 기능이다. 주요 Hooks는 다음과 같다:
- useState: 상태 관리
- useEffect: 사이드 이펙트 관리
- useContext: 전역 상태 관리
- useReducer: 복잡한 상태 로직 처리
- useRef: DOM 요소 또는 값을 참조할 때 사용
2.4 React Query 개요
React Query는 서버 상태를 효율적으로 관리하는 라이브러리로, 데이터 패칭, 캐싱, 동기화 등을 간편하게 처리할 수 있다. 주요 특징은 다음과 같다:
- 자동 캐싱 및 리페칭: 데이터를 효율적으로 관리
- 백그라운드 데이터 동기화: 최신 데이터를 유지하면서 UI 업데이트 가능
- 비동기 상태 관리 최적화: loading, error, success 상태를 편리하게 활용 가능
3. 프로젝트 레이아웃 및 컴포넌트 설계
3.1 디렉토리 구조
프로젝트의 유지보수성과 확장성을 고려하여 다음과 같은 구조를 구성했다:
src/
├── components/ # 공통 UI 컴포넌트
├── hooks/ # 커스텀 훅
├── pages/ # 페이지 단위 컴포넌트
├── services/ # API 호출 (React Query 활용)
├── stores/ # 상태 관리 (Context API 또는 Zustand)
├── utils/ # 유틸리티 함수
├── types/ # TypeScript 타입 정의
3.2 주요 컴포넌트 설계 원칙
- 재사용성을 고려한 컴포넌트 분리: UI 요소를 최대한 분리하여 여러 곳에서 재사용할 수 있도록 설계
- Props 최적화: 불필요한 re-rendering 방지를 위해 React.memo와 useCallback 활용
- 커스텀 훅 활용: 복잡한 비즈니스 로직을 별도 훅으로 관리하여 코드 가독성 및 재사용성 향상
4. React Query를 활용한 데이터 관리
4.1 React Query 적용 방식
import { useQuery } from '@tanstack/react-query';
import { fetchUpdateList } from '../services/updateService';
const useUpdateList = () => {
return useQuery(['updateList'], fetchUpdateList, {
staleTime: 1000 * 60 * 5, // 데이터 캐싱 시간 설정
retry: 2, // 요청 실패 시 재시도 횟수
});
};
export default useUpdateList;
4.2 React Query의 장점
- 서버 상태 관리가 쉬워짐
- 캐싱을 통해 API 호출 최적화
- 자동 리페치 기능으로 최신 데이터 유지
5. 주요 문제 해결 사례
5.1 React Query의 staleTime과 refetch 설정 이슈
문제: staleTime을 너무 짧게 설정하여 불필요한 요청이 많이 발생 해결: staleTime을 적절히 조정하여 네트워크 부하를 줄이고, 필요할 때만 수동으로 refetch 하도록 변경
const { data, refetch } = useQuery(['updateList'], fetchUpdateList, {
staleTime: 1000 * 60 * 5, // 5분 동안 캐싱 유지
enabled: false, // 초기 요청을 비활성화하고 필요할 때 호출
});
<button onClick={() => refetch()}>업데이트 목록 불러오기</button>
5.2 useEffect에서 API 호출을 중복하는 문제
문제: useEffect에서 API 호출 시 의존성 배열을 잘못 설정하여 불필요한 요청 발생 해결: useEffect 대신 React Query의 enabled 옵션을 활용하여 필요한 시점에만 요청 실행
const { data, isLoading } = useQuery(['updateList'], fetchUpdateList, {
enabled: shouldFetch,
});
6. 결론
이번 프로젝트에서 React 18, TypeScript, React Query, Hooks를 사용하면서 다음과 같은 점을 배웠다:
- 컴포넌트 설계 시 재사용성과 성능 최적화를 고려해야 함
- React Query를 활용하면 서버 상태 관리를 효율적으로 할 수 있음
- staleTime, enabled 등의 설정을 신중하게 해야 불필요한 API 호출을 줄일 수 있음
앞으로도 더 나은 성능과 유지보수성을 고려한 개발을 위해 지속적으로 학습하고 적용해 나갈 예정이다.
'React' 카테고리의 다른 글
이 작은 차이가 성능을 바꾼다! key={index} vs key={id} (0) | 2025.03.18 |
---|---|
React 18 + TypeScript + React Query + Hooks 실무 적용기 (0) | 2025.03.18 |