티스토리 뷰

React의 useEffect 훅은 외부 시스템과의 동기화나 Side Effect를 관리할 때 사용됩니다. 그러나 모든 상황에서 useEffect가 필요한 것은 아닙니다. 직접적인 렌더링 로직이나 이벤트 핸들러 내에서 처리할 수 있는 경우에는 useEffect를 사용하지 않음으로써 코드를 더 단순하게 만들고, 실행 속도를 빠르게 하며, 오류 가능성을 줄일 수 있습니다. 이런 경우에는useEffect 사용을 재고해야 합니다. 리액트 공식문서의 You Might Not Need an Effect를 참고로 하여 useEffect를 사용하지 않아야 하는 대표적인 패턴들을 정리해보았습니다.

useEffect의 활용 사례

먼저, useEffect를 잘 사용하는 예시입니다. useEffect는 외부 데이터를 가져오거나, 외부 API와 동기화를 수행할 때 매우 유용합니다. 예를 들어, 컴포넌트가 마운트될 때 서버에서 데이터를 가져와야 한다면 useEffect를 사용하는 것이 적절합니다.

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

function UserData() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/user')
      .then(response => response.json())
      .then(data => setUser(data));
  }, []); // 의존성 배열이 비어 있으므로 컴포넌트 마운트 시 한 번만 실행됩니다.

  if (!user) return <div>Loading...</div>;

  return <div>Username: {user.name}</div>;
}

이 코드 예시에서는 컴포넌트가 처음 렌더링될 때 사용자 데이터를 가져오기 위해 useEffect를 사용합니다. 서버에서 데이터를 비동기적으로 가져오는 과정은 부수 효과에 속하므로, useEffect 내에서 처리하는 것이 적절합니다.

useEffect를 사용하지 않아야 하는 경우들

그렇다면 이제는 React에서 useEffect를 사용하면 안 되는 몇 가지 주요 경우를 살펴보겠습니다.

1. 컴포넌트 내에서 파생된 데이터 변환

React 컴포넌트 내에서 파생된 데이터를 관리하기 위해서 useEffect가 잘못 사용되는 경우가 있습니다. 데이터 변환은 렌더링 과정에서 직접 계산될 수 있으며, useMemo를 사용하여 최적화할 수 있습니다.

// 비효율적인 예시: useEffect 사용
function InefficientExample({ items }) {
  const [filteredItems, setFilteredItems] = useState([]);

  useEffect(() => {
    setFilteredItems(items.filter(item => item.isActive));
  }, [items]);

  return <DisplayItems items={filteredItems} />;
}

// 효율적인 예시: useMemo 사용
function EfficientExample({ items }) {
  const filteredItems = useMemo(() => items.filter(item => item.isActive), [items]);

  return <DisplayItems items={filteredItems} />;
}

2. 사용자 이벤트에 대한 반응

사용자 이벤트를 처리할 때 useEffect에 의존하는 것은 권장되지 않습니다. 대신, 이벤트 핸들러 내에서 직접 로직을 처리하는 것이 바람직합니다.

// 비효율적인 예시: useEffect로 이벤트 처리
function InefficientExample() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // 사용자 이벤트에 반응
    console.log(`클릭되었습니다: ${count}번`);
  }, [count]);

  return <button onClick={() => setCount(count + 1)}>클릭</button>;
}

// 효율적인 예시: 이벤트 핸들러 내 직접 처리
function EfficientExample() {
  const handleClick = () => {
    console.log("클릭되었습니다.");
    // 이벤트 처리 로직을 여기에 작성
  };

  return <button onClick={handleClick}>클릭</button>;
}

3. State나 Prop에서 직접 계산할 수 있는 값

컴포넌트의 State나 Prop에서 직접 계산할 수 있는 값을 State로 관리하는 것은 피해야 합니다. 이러한 값은 렌더링 과정에서 직접 계산되어야 하며, 필요한 경우 useMemo로 최적화할 수 있습니다.

// 비효율적인 예시: 계산된 상태를 useEffect와 useState로 관리
function InefficientExample({ price, discount }) {
  const [finalPrice, setFinalPrice] = useState(0);

  useEffect(() => {
    setFinalPrice(price - price * discount);
  }, [price, discount]);

  return <div>최종 가격: {finalPrice}</div>;
}

// 효율적인 예시: 계산된 값을 직접 계산
function EfficientExample({ price, discount }) {
  const finalPrice = useMemo(() => price - price * discount, [price, discount]);

  return <div>최종 가격: {finalPrice}</div>;
}

이러한 접근 방식은 코드의 복잡성을 줄이고, 성능을 개선하며, 예측 가능한 React 애플리케이션을 구축하는 데 도움이 됩니다. React에서는 useEffect의 사용을 최소화하고, 렌더링 과정이나 이벤트 핸들러 내에서 직접 데이터를 처리하는 것이 권장됩니다.

위 예시에서 볼 수 있듯이, useEffect는 특정 상황에서는 대체될 수 있으며, 이를 통해 더 효율적이고 명확한 코드를 작성할 수 있습니다. 데이터 변환은 useMemo를 사용하여 렌더링 시점에 처리할 수 있으며, 사용자 이벤트는 이벤트 핸들러 내에서 직접 처리하는 것이 더 적합할 수 있습니다.

반응형

'Programming' 카테고리의 다른 글

[React.js] useEffect는 언제 실행될까?  (0) 2024.02.10
댓글