[React] Side Effect 그리고 useEffect

JINJIN·2023년 12월 18일
2

React

목록 보기
9/10
post-thumbnail

React useEffect 훅 완전 정복하기

useEffect의 의미

2018년 리액트 코어 훅(useState, useEffect 등)이 추가되었을 때, 많은 개발자들이 useEffect라는 이름에 혼란을 느꼈습니다. 그렇다면 effect란 무엇일까요?

effect란 함수형 프로그래밍 용어인 "사이드 이펙트(side effect)"를 가리킵니다. 하지만 사이드 이펙트를 이해하기 위해서는 먼저 "순수 함수(pure function)"의 개념을 이해해야 합니다.


순수 함수와 React 컴포넌트

대부분의 리액트 컴포넌트는 순수 함수로 간주됩니다. 순수 함수는 입력값에 대해 예측 가능한 출력을 반환합니다. 자바스크립트 함수의 입력은 인자(arguments)입니다. 리액트 컴포넌트의 입력은 무엇일까요? 바로 Props입니다!

export default function App() {
  return <User name="John Doe" />   
}

function User(props) {
  return <h1>{props.name}</h1>; // John Doe
}

이 예시는 주어진 입력에 대해 항상 동일한 출력을 반환합니다.


리액트에서의 사이드 이펙트(Side Effect)

사이드 이펙트(Side Effect)는 외부 세계와의 상호작용을 통해 발생하는, 예측이 어려운 결과를 말합니다. 리액트 컴포넌트가 이러한 외부 요소들과 상호작용할 필요가 있을 때, 그 결과는 항상 예측 가능한 것만은 아닙니다."

일반적인 사이드 이펙트의 예시는 다음과 같습니다.

  • 백엔드 서버로부터 데이터를 요청
  • documentwindow와 같은 브라우저 API와의 상호작용
  • setTimeout 또는 setInterval과 같은 타이밍 함수 사용

이러한 이유로 useEffect가 존재합니다. useEffect는 순수한 리액트 컴포넌트 내에서 이러한 사이드 이펙트를 처리하는 방법을 제공합니다.


useEffect 사용법

useEffect의 기본 문법은 다음과 같습니다.

// 1. useEffect 임포트
import { useEffect } from 'react';

function MyComponent() {
  // 2. JSX 반환 전에 호출
  // 3. 두 개의 인자 전달: 함수와 배열
  useEffect(() => {}, []);
  
  // return ...
}
  1. 리액트에서 useEffect를 임포트
  2. 컴포넌트 내에서 JSX를 반환하기 전에 호출
  3. 두 개의 인자를 전달: 콜백 함수의존성 배열

간단한 예시 코드를 하나 더 보여드리겠습니다!

import { useEffect } from 'react';

function User({ name }) {
  useEffect(() => {
    document.title = name;
  }, [name]);
    
  return <h1>{name}</h1>;   
}

콜백 함수는 컴포넌트 렌더링 후 호출됩니다. 의존성 배열은 사이드 이펙트가 의존하는 모든 값들을 포함해야 합니다.


useEffect와 관련된 일반적인 실수

useEffect 사용 시 주의해야 할 몇 가지 세부 사항이 있습니다.

의존성 배열을 제공하지 않으면 useEffect는 모든 렌더링 후에 실행됩니다. 이는 상태 업데이트가 있는 경우 무한 루프를 초래할 수 있습니다.

function MyComponent() {
  const [data, setData] = useState([])  
    
  useEffect(() => {
    fetchData().then(myData => setData(myData));
    // 무한 루프 위험!
  }); 
}

이처럼 useEffect 내에서 상태를 업데이트하는 경우, 빈 의존성 배열( [] )을 제공해야 합니다.

function MyComponent() {
  const [data, setData] = useState([])  
    
  useEffect(() => {
    fetchData().then(myData => setData(myData));
    // 올바른 사용법: 빈 배열로 한 번만 실행
  }, []); 
}

useEffect의 클린업 함수

사이드 이펙트의 정리(clean-up)는 리액트에서 사이드 이펙트를 올바르게 수행하는 데 있어 중요한 부분입니다. useEffect 내에서 반환하는 함수는 클린업을 위한 함수입니다. 이 함수는 컴포넌트가 언마운트(삭제)될 때 호출됩니다.

useEffect(() => {
  // 사이드 이펙트 로직

  return () => {
    // 클린업 로직
  };
}, [dependencies]);

예시를 들어보면, setInterval을 사용한 타이머가 있을 때, 컴포넌트가 언마운트(삭제)될 때 이 타이머를 정지시켜야 합니다.

function Timer() {
  const [time, setTime] = useState(0);
    
  useEffect(() => {
    let interval = setInterval(() => setTime(time + 1), 1000); 

    return () => {
      clearInterval(interval);
    }
  }, []);
}

모든 경우에 클린업 함수가 필요한 것은 아니며, 반복되는 사이드 이펙트를 컴포넌트 언마운트 시 정지시켜야 할 때 주로 사용됩니다.

profile
안녕하세요! 배우는 것을 좋아하는 개발자 JINJIN입니다.

0개의 댓글

관련 채용 정보