9.0 KiB
9.0 KiB
Functional Components
📌 Brief Summary
Functional Components(함수형 컴포넌트)는 과거 클래스 기반 컴포넌트를 대체하여 현대 React 애플리케이션 개발의 표준으로 자리 잡은 핵심 UI 작성 단위입니다 [1, 2]. 자체적으로 상태(state)와 부수 효과(side effect)를 관리하기 위해 useState, useEffect 등의 React 훅(Hooks)과 결합하여 사용됩니다 [3-5]. 강력하고 유연한 기능성을 제공하지만, 자체적으로 Error Boundary(에러 경계) 역할을 할 수 없다는 명확한 구조적 제약도 존재합니다 [6, 7].
📖 Core Content
- 훅(Hooks)을 통한 상태 및 로직 관리:
함수형 컴포넌트는
useState,useReducer,useEffect등을 사용하여 상태 관리와 부수 효과를 처리합니다 [3-5]. 훅은 반드시 컴포넌트 내부의 최상단에서만 호출되어야 하며 루프나 조건문 내에서 사용되어서는 안 됩니다 [8]. - 레거시 코드베이스의 현대화 기준: React 코드베이스를 리팩토링할 때 클래스 기반 컴포넌트를 함수형 컴포넌트와 훅으로 전환하는 것은 가장 효과적인 아키텍처 개선(solid win)으로 평가받습니다 [2].
- 소프트웨어 공학 원칙(SOLID & Clean Code)의 적용: 클래스에서 함수형으로 형태가 변했더라도 단일 책임 원칙(SRP) 등은 여전히 유효합니다 [1]. 컴포넌트가 300줄 이상 길어지거나 상태 관리, 데이터 페칭, UI 렌더링 책임을 동시에 가지게 된다면, 책임을 분리하여 더 작은 함수형 컴포넌트나 커스텀 훅으로 쪼개야 합니다 [1, 9, 10]. 이는 코드의 반복을 줄이는 DRY 원칙과 복잡성을 줄이는 KISS 원칙을 달성하는 데 필수적입니다 [11, 12].
- 컴포넌트의 참조(Reference) 동작 및 렌더링 주의점:
함수형 컴포넌트 내부에서 JSX의 props로 인라인 익명 함수(
() => {...})를 직접 넘기는 것은 지양해야 합니다 [13, 14]. 함수형 컴포넌트는 렌더링될 때마다 내부의 인라인 함수 인스턴스를 새로 생성하므로, 자식 컴포넌트에 새로운 참조(Reference)가 전달되어 불필요한 리렌더링을 유발하기 때문입니다 [14, 15].
⚖️ Trade-offs & Caveats
- Error Boundary로써의 사용 불가 (제약 사항):
함수형 컴포넌트의 가장 큰 제약 중 하나는 자체적으로 Error Boundary(에러 경계) 역할을 할 수 없다는 점입니다. 자식 컴포넌트의 에러를 잡기 위해 사용되는
getDerivedStateFromError또는componentDidCatch생명주기 메서드를 사용할 수 없으므로, 에러 처리를 위해서는 여전히 클래스 컴포넌트를 구현하거나react-error-boundary와 같은 외부 라이브러리 래퍼(Wrapper)를 사용해야 합니다 [6, 7]. - 메모리 누수와 클로저(Closure)로 인한 부작용:
함수형 컴포넌트와 훅을 사용할 때 클로저 특성으로 인해 오래된 변수나 객체가 메모리에 유지되는 'Stale Closure' 문제가 발생할 수 있습니다 [16, 17]. 특히
useEffect내부에서 이벤트 리스너를 구독(subscribe)하고 언마운트 시 클린업(cleanup) 함수로 제거하지 않으면 심각한 메모리 누수로 이어집니다 [18-20]. - 과도한 훅 사용으로 인한 복잡성(Trade-off):
무분별한
useEffect사용은 애플리케이션의 잦은 리렌더링을 유발하여 퍼포먼스를 크게 떨어뜨릴 수 있습니다 [21]. 또한 성능을 높이겠다고useCallback과useMemo를 모든 곳에 남용하는 것은 오히려 메모이제이션 비교에 드는 오버헤드가 더 커질 수 있으므로, Chrome DevTools 및 React Profiler를 통한 성능 측정이 선행된 후 꼭 필요한 곳에만 적용해야 합니다 [22-24].
🔗 Knowledge Connections
Related Concepts
[관계 유형 A: 아키텍처 및 핵심 기술]
-
[[React Hooks]]- 연결 이유: 함수형 컴포넌트가 단순한 UI 렌더링 함수를 넘어 라이프사이클 및 상태 관리를 할 수 있게 만들어주는 핵심 메커니즘이기 때문입니다 [3].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분:
useState와useEffect를 통한 상태 및 부수 효과 관리, 의존성 배열(dependency array)의 올바른 사용법 및 렌더링 사이클 [3, 4, 21].
-
[[SOLID Principles]]- 연결 이유: 함수형 컴포넌트를 설계하고 리팩토링할 때 코드를 모듈화하는 기준점(예: 단일 책임 원칙)을 제공합니다 [1, 25].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 거대한 함수형 컴포넌트를 비즈니스 로직(Custom Hooks)과 순수 UI 컴포넌트로 분리하는 클린 코드(Clean Code) 패턴 [1, 10, 11].
[관계 유형 B: 최적화 및 활용 도구]
-
[[Memoization (React.memo, useMemo, useCallback)]]- 연결 이유: 함수형 컴포넌트는 상위 컴포넌트 렌더링 시 기본적으로 함께 재실행되므로, 이를 제어하기 위한 수동 최적화 기법이 필수적으로 수반됩니다 [26, 27].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 함수와 객체의 참조 안정성(Reference Equality), 불필요한 리렌더링 차단 원리 및 잘못된 사용으로 인한 오버헤드 위험성 [14, 24, 28].
-
[[Error Boundaries]]- 연결 이유: 함수형 컴포넌트의 명확한 기술적 한계를 나타내는 기능으로, 렌더링 중 발생하는 런타임 오류를 우회 처리하기 위한 기법입니다 [7, 29].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 함수형 컴포넌트 트리를 붕괴시키지 않고, 오류 발생 시 부분적으로 폴백(fallback) UI를 제공하는 애플리케이션 안정성 확보 방법 [30, 31].
Deeper Research Questions
- 함수형 컴포넌트 도입으로 사라진 클래스 컴포넌트의 라이프사이클 메서드(예:
componentDidMount,componentDidUpdate)는useEffect내부에서 내부적으로 어떻게 대체되고 스케줄링되는가? - 함수형 컴포넌트에서 클로저(Closure) 동작으로 인해 발생하는 메모리 누수와 'Stale Closure' 문제를 Chrome DevTools (Memory Profiler)를 사용해 어떻게 추적하고 해결할 수 있는가?
- 자동 메모이제이션을 지원하는
React Compiler의 도입이 안정화될 경우, 개발자가 함수형 컴포넌트 코드를 작성하는 패턴(기존의useMemo,useCallback의존성 탈피 등)에 어떤 근본적인 변화가 일어나는가? - 왜 React 아키텍처 상 Error Boundary 기능은 함수형 컴포넌트와 훅으로 원형 그대로 구현될 수 없으며, 클래스 컴포넌트의 생명주기에만 종속되도록 설계되었는가?
- 함수형 컴포넌트에 의존성 역전 원칙(DIP)과 단일 책임 원칙(SRP)을 적용하여 UI, 서버 상태(TanStack Query), 전역 상태(Zustand)를 완벽히 격리하는 가장 모범적인 코드 구조는 무엇인가?
Practical Application Contexts
- Implementation: 클래스 컴포넌트를 배제하고
useState와useEffect를 사용해 최신 리액트 표준에 맞춰 화면 단위와 UI 요소를 구현합니다 [2, 3]. - System Design: 로직과 뷰의 강결합을 피하기 위해, 데이터 페칭과 비즈니스 로직은 별도의 Custom Hook이나 서비스 계층으로 분리하고 함수형 컴포넌트는 시각적 렌더링(Presentation) 기능만 수행하도록 시스템을 설계합니다 [9, 32].
- Operation / Maintenance: 함수형 컴포넌트 내부에서 익명 함수 및 인라인 객체가 남용되지 않도록 ESLint(
eslint-plugin-react-hooks) 및why-did-you-render같은 도구를 CI/CD 파이프라인에 통합해 불필요한 렌더링 누수를 막습니다 [33-35]. - Learning Path: (기초) JSX와 함수형 컴포넌트의 이해 ➔ (중급) React Hooks 기반 상태/라이프사이클 제어 및 커스텀 훅 분리 ➔ (고급) Memoization 기법, Closure 함정 극복 및 React Compiler 동작 원리 파악 [3, 36-38].
- My Project Relevance: 현재 레거시 코드로 이루어진 React 프로젝트를 리팩토링해야 할 경우, 클래스 컴포넌트를 모두 함수형 컴포넌트로 변환(Migration)하고 불필요한 로직을 커스텀 훅으로 들어내어 가독성 및 성능을 최적화하는 첫 번째 마일스톤으로 활용할 수 있습니다 [2, 9, 39].
Adjacent Topics
[[React Compiler]]- 확장 방향: 개발자가 함수형 컴포넌트에서 수동으로 처리하던
useMemo와useCallback의 불편함을 빌드 타임에 자동으로 분석해 최적화(Auto-memoization)해주는 미래의 React 성능 개선 도구의 원리 이해 [37, 40].
- 확장 방향: 개발자가 함수형 컴포넌트에서 수동으로 처리하던
[[Feature-Sliced Design (FSD)]]- 확장 방향: 수백 개의 함수형 컴포넌트와 커스텀 훅들이 얽힌 거대한 코드베이스를 도메인(Domain)과 기능(Feature) 단위의 계층 구조로 명확하게 모듈화하는 스케일링 방법론 탐구 [41-43].
Last updated: 2026-04-30