코드도보통지

7관문. Ref Cleanups

관문 7 / 7

컴포넌트 언마운트 시 ref에 저장된 외부 인스턴스를 완벽하게 해제하는 패턴을 구현하라.

📖 이론 비급

Ref Cleanups: 메모리 누수 방지

ref에 WebSocket, Worker, 외부 라이브러리 인스턴스를 저장할 때 언마운트 시 명시적으로 해제하지 않으면 메모리 누수가 발생한다.

패턴: useEffect의 cleanup에서 ref.current.destroy() 또는 ref.current.close()를 호출하고 ref.current = null로 참조를 끊어 GC가 수거할 수 있게 한다. cleanup이 실행될 시점에 ref.current를 로컬 변수로 미리 캡처하는 것이 안전하다.

⚔️ 수련 코드

import { useRef, useEffect, useState } from 'react';

class ExternalService {
  constructor(id) {
    this.id = id;
    console.log(`서비스 ${id} 생성`);
  }
  destroy() {
    console.log(`서비스 ${this.id} 해제`);
  }
}

export default function ServiceConsumer({ serviceId }) {
  const serviceRef = useRef(null);

  useEffect(() => {
    serviceRef.current = new ExternalService(serviceId);
    return () => {
      // TODO: 로컬 변수 캡처 패턴으로 안전하게 해제하라
      // serviceRef.current를 지역 변수에 저장 후 destroy 호출
      // serviceRef.current = null 로 참조 해제
    };
  }, [serviceId]);

  return <p>서비스 ID: {serviceId}</p>;
}