today's helen

seize!

web

HTML/CSS(Styled-Component) 프로젝트에 디자인 시스템 도입하기

yooncandooit 2026. 7. 8. 15:53
반응형

useEffect에서 side effect를 처리하는 법을 배워보자

우선, Side Effect란?

  • 비동기 작업을 처리할 때 사용되는 것들
    • 렌더링과 관계없이 발생하는 동작 (ex: API 요청, 타이머, document.title 변경 등등)

⚠️ 기존 문제점: 리액트의 “비동기” 처리

  • 여태까진 useState를 사용해 상태를 관리했지만, BUT 상태가 즉시 반영되지 않음
  • 마운팅되는 count 값 ≠ console.log()에 찍히는 count

왜냐?React의 상태 업데이트는 기본적으로 비동기적이기 때문

즉, setState 호출 직후 console.log(count) 실행하면, count++하기 전, 즉 업데이트되기 전의 값이 찍히는 문제가 발생한다


** 해결 방법: useEffect 사용**

setState부터 useEffect, return까지의 코드에서 작동 순서를 정리해보았다

useEffect(() => {
  console.log(count); // 의존성 배열의 값이 변경될 때마다 실행
}, [count]);

** 위 코드의 동작 과정**

  1. setCount(count + 1); 실행됨 (비동기 처리로 인해 즉시 업데이트되지 않음)
  2. 리렌더링 발생return (...) 내부 JSX 코드가 실행됨, 즉 브라우저 화면에 최신 값이 반영됨
  3. 렌더링 완료 후, count 값이 변경되었으므로 useEffect 내의 코드가 실행됨
    • 즉, console.log(count);!!최신 값을 반환!!한다

이후, 의존성 배열 안의 state가 변경될 때마다 과정 2 ↔ 3이 반복됨

** 그래서 정리하자면…**

  • return (JSX)이 반환하는 값 = 업데이트 전의 state인count 값을 출력한다
  • useEffect = 업데이트 후의 최신 count
  • 즉, useEffect를 사용하면 state의 latest 값이 보장됨 → 비동기 처리 문제 해결!

목표 2: useEffect의 clean up 함수를 써야 하는 이유 알아보자

useEffect(() => {
  let i = 0;
  const counterInterval = setInterval(() => {
    console.log(i);
    i++;
  }, 1000);
}, []);

이해를 위해, 우선 이런 코드가 있다고 하자

이 코드에서 발생하는 문제?

  • setInterval()이 실행될 때, 1초마다 i++을 실행한다
  • But, 컴포넌트가 여러 번 렌더링되거나 or useEffect가 재실행된다면?
    • setInterval()이 중복 실행됨 → 여러 개의 setInterval()이 사진처럼 동시에 작동하게 됨

즉, useEffect가 여러 번 실행되거나 컴포넌트가 여러 번 렌더링되면
→ 불필요한 비효율적인 동작이 발생 (중복 실행)
이렇게 불필요한 동작이 지속되면서 성능이 저하된다

해결 방법: clean up 함수 사용

useEffect 내부의 기존 동작을 정리하고, 새로운 useEffect를 실행할 수 있도록 함

useEffect(() => {
  let i = 0;
  const counterInterval = setInterval(() => { // setInterval 함수에 counterInterval이라는 변수명을 부여해줌
    console.log(i);
    i++;
  }, 1000);

    return (): void => {
        console.log("언마운트");
           clearInterval(counterInterval); 
      // clean up 함수를 작성: 기존의 setInterval을 제거 -> 중복 실행 방지!
      };
  }, []);

clean up 함수의 역할

  1. 이전 useEffect의 내용을 정리 (clearInterval() 사용)
  2. 새로운 useEffect 실행 → 중복 실행 방지

즉, 기존의 setInterval을 제거하고 새로운 setInterval을 설정하는 것!

즉,

  1. 기존의 setInterval을 제거 (중복 방지)
  2. 그리고 새로운 useEffect가 실행되며 새로운 함수 setInterval이 설정됨!

🚨 useEffect 사용 시, 주의할 점

무한 루프를 발생시키는 패턴

useEffect(() => {
  setCount(count + 1); // (1)
}, [count]); // (2) 의존성 배열 count가 변경될 때마다 useEffect 내부 코드가 실행됨

문제점:

(1) : count + 1 하는 초기 렌더링 시작 (값이 변경됨)
(2) : count 값이 변경될 때마다 (1) 실행
(3) : 뭔가 논리가 이상..? -> !!무한 루프 발생!!

해결 방법

  • useEffect 내부에서 의존성 배열의 값을 직접 변경하면 안 됨!
  • 상태를 변경해야 한다면, useEffect가 아닌 이벤트 핸들러나 별도의 함수에서 수행해야 함

정리

✔️ useEffect비동기 작업(Side Effect)을 수행하는 데 사용됨
✔️ 의존성 배열을 활용해서, 특정 값이 변경될 때만 useEffect가 실행되도록 제어 가능
✔️ clean up 함수를 사용하여 불필요한 동작을 정리하고, 성능 최적화 가능
✔️ 의존성 배열 안의 값을 useEffect 내부에서 변경하면 안 됨! (무한 루프 주의)


반응형