개발브롞으

[React] useEffect, useEffect의 정리 함수 - 이론 설명, 활용 예제 본문

WEB/React

[React] useEffect, useEffect의 정리 함수 - 이론 설명, 활용 예제

총명한 주인장 2025. 10. 29. 03:47
728x90
728x90

이번 글은 useEffect에 대한 글이다.


 

[ useEffect ]

* 사이드 이펙트 : 컴포넌트가 렌더링 외 다른 영향을 주거나 외부에서 데이터를 가져오는 일

(JSX 반환 외 모든 부가적인 일을 말함)

=> API 호출, DOM 조작, 콘솔 출력 등

 

=> 따라서, 사이드 이펙트를 컴포넌트 함수 본문이 아닌 useEffect를 사용해서 실행

 

 

 

 

- useEffect의 구조

=> 콜백함수 : 실행할 콜백함수 (사이드 이펙트를 발생시키는 부분)

=> dependencies 배열 : 이 배열의 값이 변경될 때마다 콜백함수 실행

(따라서 배열이 []이면 최초 마운트 때 한번만 실행되고 값이 계속 바뀌면 계속 해당 콜백함수를 실행함)

useEffect(콜백함수, dependencies);

 

아래 예제는 콜백함수를 count가 변경될 때마다 계속 실행해줌

useEffect(() => {
    console.log("렌더링 후 실행됨!");
  }, [count]);

 

 

 

 

 

🔽useEffect 예제🔽

더보기
import { useEffect, useState } from "react";

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("렌더링 후 실행됨!");
  }, [count]); // ← 의존성 배열
}

 

 

 

 

- Dependencies 상황별 활용

[] (빈 배열)

  • API 호출 (컴포넌트가 처음 렌더링될 때 데이터 불러오기)
  • 한 번만 실행해야 하는 설정 코드 (예: 이벤트 리스너 등록, 초기값 세팅)
  • cleanup(정리) 코드와 함께 unmount 시 동작 처리

 

[(내용)]

  • 특정 state가 변할 때마다 후속 처리 (ex. count 값이 바뀔 때마다 서버에 저장, 콘솔 출력, DOM 변경 등)
  • 다른 값과 연동되어야 하는 로직 (예: 검색어 state가 바뀔 때 API 재요청)

 


 

 

[ useEffect의 정리 함수 ]

정리 함수 : useEffect는 사이드 이펙트를 다루는데 이 사이드 이펙트가 계속 실행되지 않도록 사용이 종료된 사이드 이펙트의 동작을 멈춰주는 역할을 함

 

 

- 정리 함수 사용하기

=> useEffect의 리턴 부분에서 콜백함수의 실행 부분에 정리함수를 넣어 실행해줌

(이전에 발생했던 사이드 이펙트 정리 & 언마운트하기 전 사이드 이펙트 정리)

return () => {
      console.log("🧼 타이머 정리!");
      clearInterval(timer);
    };

 

🔽useEffect 예제🔽

더보기
import { useEffect, useState } from "react";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("⏰ 타이머 시작!");
    const timer = setInterval(() => {
      setCount(prev => prev + 1);
    }, 1000);

    // 🧹 cleanup 함수
    return () => {
      console.log("🧼 타이머 정리!");
      clearInterval(timer);
    };
  }, []); // 처음 한 번만 실행

  return <div>{count}초</div>;
}

export default Timer;

 

 


 

 

[ 활용 예제 ]

문제 : setInterval() 함수를 사용해서 3초마다 캐러셀이 자동으로 넘어가도록 구현

 

- 문제에서 수정한 코드 부분

  useEffect(()=>{
      const intervalId = setInterval(()=>{
          handleNext();
      }, 3000);
      return () => clearInterval(intervalId);
  }, []);

 

=> useEffect를 사용해 3초마다 캐러셀이 자동으로 변경되는 사이드 이펙트를 처리해줌

 

=> setInterval()을 사용해 일정 시간마다 특정 코드를 반복시킴

     setInterval()의 구조 : 반복해서 실행할 함수, 실행 간격 (ms 단위로 전달)

setInterval(callback, delay);

 

=> 정리 함수로 intervalId를 넣어줌

 

=> useEffect의 dependencies로 []을 넣어주어 최초 마운트 이후에만 계속 3초 뒤 실행하는 콜백함수의 내용이 지속되게 함

 

 


 

🔽수정 전 코드🔽

더보기
import { useState } from 'react';

function Carousel({ images }) {
  const [currentIndex, setCurrentIndex] = useState(0);

  const handlePrev = () => {
    if (currentIndex === 0) {
      setCurrentIndex(images.length - 1);
      return;
    }
    setCurrentIndex(currentIndex - 1);
  };

  const handleNext = () => {
    if (currentIndex === images.length - 1) {
      setCurrentIndex(0);
      return;
    }
    setCurrentIndex(currentIndex + 1);
  };

  return (
    <div>
      <button onClick={handlePrev}>이전</button>
      <img src={images[currentIndex]} alt="carousel" />
      <button onClick={handleNext}>다음</button>
    </div>
  );
}

export default Carousel;

 

🔽수정 후 코드🔽

더보기
import { useEffect, useState } from 'react';

function Carousel({ images }) {
  const [currentIndex, setCurrentIndex] = useState(0);

  const handlePrev = () => {
    if (currentIndex === 0) {
      setCurrentIndex(images.length - 1);
      return;
    }
    setCurrentIndex(currentIndex - 1);
  };

  const handleNext = () => {
    if (currentIndex === images.length - 1) {
      setCurrentIndex(0);
      return;
    }
    setCurrentIndex(currentIndex + 1);
  };
  
  useEffect(()=>{
      const intervalId = setInterval(()=>{
          handleNext();
      }, 3000);
      return () => clearInterval(intervalId);
  }, [])

  return (
    <div>
      <button onClick={handlePrev}>이전</button>
      <img src={images[currentIndex]} alt="carousel" />
      <button onClick={handleNext}>다음</button>
    </div>
  );
}

export default Carousel;

 


728x90
728x90
Comments