자바스크립트 + 리액트 디자인 패턴 스터디

·2025년 7월 31일

리액트 Hooks 패턴

클래스 컴포넌트를 사용하지 않고도 상태와 라이프사이클 메서드 활용 가능
Hooks 자체는 디자인 패턴이라고 할 수 없으나 많은 전통적 디자인 패턴 대체 가능

1. 클래스 컴포넌트의 한계

  • 클래스 컴포넌트의 특징

    • 생성자 함수에서 상태 관리
    • componentDidMount, componentWillUnmount 등 라이프사이클 메서드 사용
    • 커스텀 메서드로 로직 추가
  • 하지만 함수형 컴포넌트를 클래스 컴포넌트로 리팩토링할 경우?

    • 클래스 문법에 대한 이해가 필요함
    • 데이터 흐름을 깨지 않고 변환하기 어렵고 복잡함

2. 구조 변경의 어려움

  • 여러 컴포넌트 간 코드 공유는 보통 다음 두 패턴 사용

    • 고차 컴포넌트(컴포넌트를 인자로 받아 새로운 컴포넌트를 반환하는 함수)
    • 렌더 Props 패턴
  • 하지만 이런 패턴을 적용하거나 변경하려면?

    • 전체 애플리케이션 구조를 변경해야 할 수 있음
    • 컴포넌트가 클수록 구조 변경이 어려움
    • 컴포넌트 중첩이 심화되어 “Wrapper Hell” 발생 가능
      → 데이터 흐름이 복잡해지고 디버깅이 어려워짐

3. 복잡성 증가

  • 클래스 컴포넌트에 로직이 많아질수록?

    • 파일 크기와 복잡도가 빠르게 증가함
    • 로직이 얽혀 구조화되지 않음
    • 특정 로직이 어디서 쓰이는지 파악이 어려움
    • 디버깅과 성능 최적화 어려움
    • 라이프사이클 메서드 간 코드 중복 발생

4. Hooks의 등장

  • 위 문제를 해결하기 위해 React 16.8부터 Hooks 도입

  • 리액트 훅을 사용하면?

    • 함수형 컴포넌트에서도 상태 관리 가능 (useState)
    • 라이프사이클 관리 가능 (useEffect)
    • 여러 컴포넌트 간 상태 관련 로직의 재사용 용이

상태 Hook

1. 상태 Hook: useState

  • 함수형 컴포넌트에서 상태(state)를 관리할 수 있게 해주는 Hook
  • 사용 전 import { useState } from 'react'로 리액트에서 불러와야 함
  • useState초기 상태값(initial state) 을 인자로 받음
  • 반환값은 배열 형태로 두 가지를 제공
    • const [state, setState] = useState(initialValue);
    • state: 현재 상태 값 → 클래스 컴포넌트의 this.state.value와 유사
    • setState: 상태를 업데이트하는 함수 → this.setState()와 유사

2. 이펙트 Hook: useEffect

  • useEffect는 컴포넌트의 라이프사이클 메서드를 대체할 수 있는 Hook
  • componentDidMount, componentDidUpdate, componentWillUnmount를 하나로 통합하여 처리할 수 있음
라이프사이클 메서드 (클래스형)useEffect 사용 방식 (함수형)설명
componentDidMountuseEffect(() => { ... }, [])컴포넌트 마운트 시 1회 실행
componentWillUnmountuseEffect(() => { return () => { ... } }, [])컴포넌트 언마운트 시 실행
componentDidUpdateuseEffect(() => { ... }, [deps])지정한 deps 변경 시마다 실행

3. 커스텀 Hook

  • use로 시작하는 이름으로 함수 작성 (리액트가 규칙 준수 여부 판단)
  • 공통 로직을 추출해 재사용 가능
  • 직접 작성 가능하며, 외부에서 공유된 Hook도 설치해 사용 가능

주요 기본 Hook

useState

  • 함수형 컴포넌트에서도 상태 관리 가능
  • const [state, setState] = useState(initialValue) 형태

useEffect

  • 렌더링 이후 실행되는 부수 효과 처리
  • 타이머, API 호출, 이벤트 등록 등
  • 클래스의 componentDidMount, componentDidUpdate, componentWillUnmount 대체

useContext

  • Context API 상태를 쉽게 사용
  • props drilling 없이 전역 상태 접근 가능
  • context 객체를 인자로 받음

useReducer

  • 복잡한 상태 로직, 상태 간 의존 관계 처리에 적합
  • const [state, dispatch] = useReducer(reducer, initialState)
  • 트리 깊은 구조에서의 성능 최적화에 효과적

Hook의 장단점

관심사 기반 코드 구성

  • 라이프사이클이 아닌 기능 단위로 코드 정리 → 가독성 향상

클래스 불필요

  • JS 클래스 관리 어려움 해결
  • 핫 리로딩 호환, 함수형 프로그래밍 용이

복잡한 로직 추출 가능

  • 고차 컴포넌트, render props 없이도 상태 로직 공유 가능
  • 테스트 및 재사용 쉬운 순수 함수로 구성 가능

규칙 엄수 필요

  • 컴포넌트의 최상위에서만 호출 (조건문/반복문 내 사용 금지)
  • use로 시작할 것 : Linter(ESLint + React Hooks plugin)로 규칙 위반 감지 가능

학습 곡선 존재

  • useEffect, useCallback, useMemo는 잘못 사용 시 성능 문제 유발

0개의 댓글