> Hello World !!!

     

@syaku

Reactjs - useEffect 와 의존성 배열 완벽 가이드

반응형

React의 useEffect와 의존성 배열 완벽 가이드

React의 useEffect는 컴포넌트의 생명주기와 관련된 부수 효과(side effects)를 처리하는 핵심 Hook입니다. 특히 의존성 배열(dependency array)의 올바른 사용은 애플리케이션의 성능과 안정성에 큰 영향을 미칩니다.

useEffect의 기본 구조

useEffect(() => {
  // 실행할 코드

  return () => {
    // 클린업 코드
  }
}, [의존성1, 의존성2, ...]);

의존성 배열의 세 가지 사용 패턴

1. 빈 배열 사용

useEffect(() => {
  console.log('컴포넌트 마운트 시에만 실행');
}, []);
  • 컴포넌트가 처음 마운트될 때만 실행
  • 주로 초기 데이터 fetch나 이벤트 리스너 등록에 사용

2. 의존성이 있는 배열

useEffect(() => {
  console.log(`count가 ${count}로 변경됨`);
}, [count]);
  • 지정된 의존성(count)이 변경될 때마다 실행
  • 특정 상태나 props의 변화에 반응해야 할 때 사용

3. 의존성 배열 생략

useEffect(() => {
  console.log('매 렌더링마다 실행');
});
  • 컴포넌트가 리렌더링될 때마다 실행
  • 성능 문제가 발생할 수 있어 주의 필요

클린업 함수의 역할

useEffect(() => {
  const subscription = api.subscribe();

  // 클린업 함수
  return () => {
    subscription.unsubscribe();
  };
}, [api]);
  • 메모리 누수 방지
  • 이벤트 리스너 제거
  • 이전 상태 정리
  • 다음 경우에 실행됨:
    1. 컴포넌트 언마운트 시
    2. 의존성이 변경되어 effect가 재실행되기 전

의존성 배열 사용 시 주의사항

1. 잘못된 의존성 설정

// 잘못된 예
useEffect(() => {
  setTotal(count * price);
}, []); // count와 price가 변경되어도 total이 업데이트되지 않음

// 올바른 예
useEffect(() => {
  setTotal(count * price);
}, [count, price]);

2. 객체와 배열 의존성

// 주의가 필요한 경우
useEffect(() => {
  doSomething(options);
}, [options]); // options가 객체라면 매 렌더링마다 새로 생성될 수 있음

// 해결 방법
useEffect(() => {
  doSomething(options.id, options.type);
}, [options.id, options.type]); // 필요한 프로퍼티만 의존성으로 지정

실제 사용 예시

1. API 호출

useEffect(() => {
  const fetchData = async () => {
    setLoading(true);
    try {
      const response = await api.getData(id);
      setData(response);
    } catch (error) {
      setError(error);
    } finally {
      setLoading(false);
    }
  };

  fetchData();
}, [id]); // id가 변경될 때만 API 재호출

2. 이벤트 리스너

useEffect(() => {
  const handleResize = () => {
    setWindowSize({
      width: window.innerWidth,
      height: window.innerHeight
    });
  };

  window.addEventListener('resize', handleResize);

  return () => {
    window.removeEventListener('resize', handleResize);
  };
}, []); // 마운트 시에만 리스너 등록

성능 최적화 팁

  1. 필요한 의존성만 포함하기
useEffect(() => {
  // user.name만 사용한다면
}, [user.name]); // user 객체 전체 대신 필요한 속성만 의존성으로 지정
  1. 함수 의존성 제거하기
useEffect(() => {
  // 함수를 effect 내부로 이동
  const handleData = () => {
    // ...
  };

  handleData();
}, [필요한_의존성만]);
  1. useCallback과 함께 사용
const memoizedCallback = useCallback(() => {
  doSomething(dependency);
}, [dependency]);

useEffect(() => {
  memoizedCallback();
}, [memoizedCallback]);

결론

useEffect와 의존성 배열의 올바른 사용은 React 애플리케이션의 성능과 안정성에 큰 영향을 미칩니다. 의존성 배열을 신중하게 설정하고, 클린업 함수를 적절히 활용하며, 성능 최적화를 고려하는 것이 중요합니다.

반응형