리액트 훅 살펴보기 - useEffect

shooting star·2024년 7월 11일
post-thumbnail

리액트 훅 살펴보기 - useEffect

React의 useEffect 훅은 함수형 컴포넌트에서 부수 효과를 관리하는 강력한 도구입니다. 이 블로그 포스트에서는 기본 개념부터 세부적인 내용까지 다루고 예제를 통해 useEffect를 마스터하는 방법을 안내합니다.

useEffect란 무엇인가?

useEffect는 두 개의 인수를 받는 훅입니다: 콜백 함수(효과)와 의존성 배열입니다. 의존성 배열의 값이 변경될 때마다 콜백 함수가 실행됩니다. 이 훅은 클래스 컴포넌트의 생명주기 메서드와 유사한 동작을 흉내낼 수 있습니다.

import React, { useEffect, useState } from 'react';

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

    useEffect(() => {
        console.log(`Count가 업데이트 되었습니다: ${count}`);
        return () => {
            console.log('클린업 함수가 호출되었습니다');
        };
    }, [count]);

    return (
        <div>
            <p>{count}</p>
            <button onClick={() => setCount(count + 1)}>증가</button>
        </div>
    );
}

위의 예제에서 효과는 count 값이 변경될 때마다 현재 값을 로그로 출력합니다. 클린업 함수는 다음 효과가 실행되기 전에 또는 컴포넌트가 언마운트될 때 실행됩니다.

상세 설명

기본 정의는 맞지만, useEffect는 단순히 의존성 배열과 클린업 함수 이상입니다. 이는 다양한 컴포넌트 상태와 props에 기반하여 애플리케이션에서 부수 효과를 동기적으로 관리하는 메커니즘입니다.

효과의 의존성

useEffect의 두 번째 인수는 다음과 같습니다:

  • 값이 있는 배열: 배열 내의 값이 변경될 때 효과가 실행됩니다.
  • 빈 배열: 최초 렌더링 후 한 번만 실행됩니다.
  • 생략: 매 렌더링마다 효과가 실행됩니다.

작동 원리

렌더링 시 React는 현재 의존성 배열과 이전 의존성 배열을 비교합니다. 값이 변경되면 효과를 실행합니다. 이 비교는 얕은 동등성 검사(Object.is 기반)로 수행됩니다.

클린업 함수

클린업 함수는 단순히 언마운트 시에만 실행되는 것이 아닙니다. 컴포넌트가 리렌더링되기 전, 다음 효과가 실행되기 전에도 실행됩니다. 이를 통해 최신 효과만 활성화됩니다.

사용 사례

  1. 데이터 가져오기: 컴포넌트가 마운트된 후 데이터를 가져오기 위해 사용됩니다.
  2. 이벤트 리스너: 이벤트 리스너를 추가하고 제거할 때 사용됩니다.
  3. 타이머: 간격이나 타임아웃을 설정하고 이를 정리할 때 사용됩니다.

예제: 데이터 가져오기

import React, { useEffect, useState } from 'react';

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

    useEffect(() => {
        const fetchData = async () => {
            const response = await fetch('https://api.example.com/data');
            const result = await response.json();
            setData(result);
        };

        fetchData();
    }, []);

    return (
        <div>
            {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : '로딩 중...'}
        </div>
    );
}

클린업과 리렌더링

다음은 이벤트 리스너를 설정하는 효과의 예제입니다:

import React, { useEffect } from 'react';

function EventListenerComponent() {
    useEffect(() => {
        const handleResize = () => {
            console.log('창 크기가 변경되었습니다');
        };

        window.addEventListener('resize', handleResize);

        return () => {
            window.removeEventListener('resize', handleResize);
        };
    }, []);

    return <div>창 크기를 변경하고 콘솔을 확인하세요.</div>;
}

클린업 함수는 이벤트 리스너를 제거하여 여러 핸들러가 누적되는 것을 방지합니다.

베스트 프랙티스

  1. 효과를 작고 구체적으로 유지: 큰 효과를 피하고 최소한의 의존성을 가진 작은 효과로 분리합니다.
  2. 불필요한 외부 함수 피하기: 관련 로직을 효과 내부로 가져와 코드의 간결성을 유지합니다.
  3. 비동기 함수 주의: 비동기 함수를 직접 useEffect에 전달하지 말고 내부에서 호출합니다.

예제: 비동기 함수 사용 주의

import React, { useEffect, useState } from 'react';

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

    useEffect(() => {
        let isMounted = true;

        const fetchData = async () => {
            const response = await fetch('https://api.example.com/data');
            const result = await response.json();
            if (isMounted) setData(result);
        };

        fetchData();

        return () => {
            isMounted = false;
        };
    }, []);

    return (
        <div>
            {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : '로딩 중...'}
        </div>
    );
}

결론

useEffect 훅은 함수형 React 컴포넌트에서 부수 효과를 관리하는 데 필수적입니다. 그 특성과 베스트 프랙티스를 이해하면 컴포넌트를 성능 좋고 예측 가능하게 유지할 수 있습니다.

0개의 댓글