---
category: Frontend
tags: [auto-wikified, technical-documentation, frontend]
title: React Hooks (useState, useEffect)
description: "React Hooks(`useState`, `useEffect` 등)는 클래스 컴포넌트를 대체하여 함수형 컴포넌트 내에서 상태(State) 관리와 부수 효과(Side Effects) 처리를 더욱 깔끔하고 간결하게 수행할 수 있도록 제공되는 모던 설계 패턴입니다 [..."
last_updated: 2026-05-04
---

# React Hooks (useState, useEffect)

## 📌 Brief Summary
React Hooks(`useState`, `useEffect` 등)는 클래스 컴포넌트를 대체하여 함수형 컴포넌트 내에서 상태(State) 관리와 부수 효과(Side Effects) 처리를 더욱 깔끔하고 간결하게 수행할 수 있도록 제공되는 모던 설계 패턴입니다 [1, 2]. 상태 기반의 로직을 추출하여 컴포넌트 간의 복잡한 중첩(Nesting) 없이도 손쉽게 코드를 재사용할 수 있도록 함수 합성(Function Composition) 방식을 지원합니다 [3-5].

## 📖 Core Content
* **상태 및 부수 효과 관리의 단순화:** `useState`와 `useEffect` 훅은 함수형 컴포넌트를 더 깨끗하고 간결하게 만들며 기존 클래스 기반 컴포넌트의 필요성을 대체합니다 [1].
* **커스텀 훅(Custom Hooks) 패턴으로의 확장:** `useState`, `useEffect`와 같은 기본 훅들을 조합하여 `use` 접두사로 시작하는 커스텀 훅을 생성할 수 있습니다 [3, 4]. 이를 통해 API 데이터 페칭, 폼 상태 관리, 반응형 디자인 핸들링 등 렌더링과 무관한 복잡한 순수 로직을 캡슐화(Encapsulate)하고, 여러 컴포넌트에서 중복 없이 재사용할 수 있습니다 [5, 6].
* **기존 패턴의 한계 극복:** 렌더 프로프(Render Props)나 고차 컴포넌트(HOC) 방식이 종종 초래하던 깊은 코드 중첩(Wrapper Hell) 문제 및 복잡한 프로퍼티 전달 문제를 불필요한 JSX 중첩 없이 깔끔하게 해결해 줍니다 [3-5].
* **서버 컴포넌트(RSC) 환경에서의 제약:** React 서버 컴포넌트는 서버에서만 실행되므로 상태(State)를 가지거나 이펙트(Effects)를 발생시킬 수 없습니다 [7]. 따라서 `useState`나 `useEffect`와 같은 훅은 이벤트 핸들러나 상태 관리가 필요한 클라이언트 컴포넌트(명시적으로 `'use client'`가 선언된 영역) 내에서만 사용되어야 합니다 [7, 8].

## ⚖️ Trade-offs & Caveats
* **엄격한 훅의 규칙 준수 필수:** 훅 패턴은 로직의 재사용성이 뛰어나다는 장점이 있지만, 컴포넌트나 커스텀 훅의 최상위에서만 호출해야 하는 등 '훅의 규칙(Rules of Hooks)'을 엄격하게 준수하지 않으면 에러를 유발하기 쉽습니다 [2, 5].
* **오래된 클로저(Stale Closure) 문제:** `useEffect` 등을 활용해 커스텀 훅을 작성할 때, 참조된 모든 값을 의존성 배열(Dependency Array)에 포함시켜야 합니다. 그렇지 않으면 렌더링 당시의 오래된 데이터를 참조하는 문제가 발생할 수 있으며, 이를 방지하기 위해 `eslint-plugin-react-hooks`의 `exhaustive-deps` 린트(Lint) 규칙 사용이 권장됩니다 [9].
* **클린업(Cleanup) 처리 누락 주의:** `useEffect` 내부에서 이벤트 리스너를 추가하거나 외부 리소스를 구독할 때, 메모리 누수를 방지하기 위해 반환값으로 클린업(Cleanup) 함수를 제공하는 것을 잊는 것은 흔한 실수이자 피해야 할 안티 패턴입니다 [9, 10].
* **과도한 맹목적 최적화(Vibe Coding)의 위험성:** 실제 성능 측정 없이 튜토리얼 등을 모방하여 무분별하게 `useCallback`, `React.memo`와 같은 훅을 모든 곳에 남용하는 것은 오히려 코드를 읽고 디버깅하기 어렵게 만들고 실제 성능을 더 악화시킬 수 있습니다 [11, 12].


---
*Last updated: 2026-05-03*