본문 바로가기

[React]

React에서 useEffect(() => {}, [])를 쓰는 이유

 

React를 처음 접했을 때 useEffect(() => {...}, [])처럼 빈 배열이 왜 필요한지 의아했던 적 있지 않으신가요?

이 글에서는 useEffect의 기본 개념부터, 왜 종종 "빈 배열"을 함께 사용하는지에 대해 하나하나 쉽게 정리해볼게요.


1️⃣ useEffect란?

useEffect는 React 컴포넌트가 렌더링될 때 부수 효과(side effect) 를 실행할 수 있게 해주는 Hook입니다.

부수 효과란?

  • 데이터를 불러오는 작업 (fetch)
  • 이벤트 리스너 등록
  • 타이머 설정
  • 콘솔 출력, 로깅 등
useEffect(() => {
  console.log("컴포넌트가 렌더링되었어요!");
});

이 코드는 컴포넌트가 렌더링될 때마다 콘솔에 로그를 찍어요.


2️⃣ useEffect의 두 번째 인자, dependency array

useEffect는 두 개의 인자를 받습니다:

useEffect(() => {
  // 실행할 코드
}, [/* 의존성 배열 */]);

여기서 두 번째 인자는 "언제 이 effect를 실행할지"를 React에게 알려주는 역할을 해요.

의존성 배열 값 설명

없음 매 렌더링마다 실행됨
빈 배열 [] 첫 렌더링(마운트) 때만 실행됨
[value] value가 변경될 때마다 실행됨

3️⃣ 빈 배열 []을 넣는 이유는?

컴포넌트가 마운트될 때 단 한 번만 실행하고 싶을 때

예: 서버에서 데이터를 처음 한 번만 가져오고 싶을 때

useEffect(() => {
  fetchData();  // 처음 한 번만 실행
}, []);

[]은 의존성이 없다는 의미!
즉, 이 effect는 처음 렌더링될 때 한 번만 실행된다는 뜻입니다.

이건 클래스형 컴포넌트의 componentDidMount()와 동일한 역할을 합니다.


4️⃣ 실전 예시

import { useEffect, useState } from "react";

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    async function fetchData() {
      const res = await fetch("https://api.example.com/data");
      const json = await res.json();
      setData(json);
    }

    fetchData();
  }, []);

 return <div>{data ? "데이터 로드 완료!" : "로딩 중..."}</div>;
}

 

 

이 경우, useEffect 안의 fetch 함수는 딱 한 번만 실행됩니다.


5️⃣ 의존성 배열을 잘못 쓰면 생기는 문제

의존성 배열을 비워야 할 상황에서 값을 넣거나, 반대로 넣어야 할 상황에서 비우면 다음과 같은 문제가 생길 수 있어요:

❗ 무한 루프

useEffect(() => {
  setData("hello");
}, [data]);
  • setData가 실행되면 data가 바뀌고
  • 다시 effect가 실행되고…
  • 무한 반복 😱

그래서 의존성 배열 설정은 신중하게 해야 합니다!


6️⃣ 요약 정리

코드 실행 시점

useEffect(() => {}) 매 렌더링마다
useEffect(() => {}, []) 마운트 시 한 번만
useEffect(() => {}, [값]) 값이 바뀔 때마다

📌 마무리

useEffect(() => {...}, [])는 한 번만 실행되는 효과를 만들기 위한 가장 기본적인 패턴입니다.
초기 데이터 로드, 구독 설정, 타이머 설정 등 초기화 작업이 필요한 경우에 자주 사용되죠.


📎 참고 링크