언어 및 도구들 공부/React

useMemo와 useEffect 차이

Dr.Mlem 2024. 12. 10. 16:06

Q1.

useMemo와 useEffect의 차이점에 대해서 좀 더 설명해줄 수 있겠어?

 
 
 
A1.

ChatGPT의 말:

 

물론입니다! useMemo와 useEffect는 둘 다 React에서 의존성 배열을 사용하지만, 목적과 동작 방식이 다릅니다. 각각의 역할과 차이점을 상세히 살펴보겠습니다.


useMemo란?

  • 주요 목적: 값을 메모이제이션하여 불필요한 재계산을 방지하고 성능을 최적화합니다.
  • 반환값: 계산된 을 반환합니다.
  • 사용 사례:
    • 계산 비용이 높은 작업(예: 복잡한 수학 계산, 데이터 필터링 등)을 메모이제이션.
    • 특정 값이 바뀌지 않으면 이전 계산 결과를 재사용.

동작 과정

  1. 의존성 배열에 포함된 값이 변경될 때만 계산 함수를 실행합니다.
  2. 계산된 결과를 메모리에 저장하고, 다음 렌더링에서도 동일한 값을 반환합니다.

예제: 복잡한 계산을 메모이제이션

import React, { useState, useMemo } from "react";

function Example() {
  const [count, setCount] = useState(0);
  const [otherState, setOtherState] = useState(0);

  const expensiveCalculation = useMemo(() => {
    console.log("Expensive calculation running...");
    return count * 2;
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Other State: {otherState}</p>
      <p>Result of Expensive Calculation: {expensiveCalculation}</p>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <button onClick={() => setOtherState(otherState + 1)}>Increment Other State</button>
    </div>
  );
}
  • 의존성 배열: [count] (count가 변경될 때만 재계산).
  • otherState를 변경해도 계산 함수는 실행되지 않음.
  • 계산 결과는 useMemo가 메모이제이션하여 재사용.

useEffect란?

  • 주요 목적: **부수 효과(side effects)**를 처리합니다. 여기서 부수 효과란, 컴포넌트 렌더링 외의 작업(데이터 가져오기, DOM 조작 등)을 의미합니다.
  • 반환값: 반환값이 없습니다.
  • 사용 사례:
    • API 호출.
    • DOM 조작(스크롤 이벤트, 애니메이션 등).
    • 구독/클린업 작업(예: WebSocket, 타이머 설정 등).

동작 과정

  1. 컴포넌트가 렌더링되거나, 의존성 배열에 포함된 값이 변경될 때 실행됩니다.
  2. 옵션으로 클린업 함수를 반환하여, 컴포넌트가 언마운트되거나 재실행 전에 정리 작업을 수행합니다.

예제: 데이터 가져오기

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

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

  useEffect(() => {
    console.log("Fetching data...");
    fetch("https://jsonplaceholder.typicode.com/posts/1")
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []); // 빈 배열이므로 컴포넌트 마운트 시 한 번 실행

  return (
    <div>
      {data ? <p>{data.title}</p> : <p>Loading...</p>}
    </div>
  );
}
  • 의존성 배열: [] (빈 배열이므로 컴포넌트 마운트 시에만 실행).
  • 데이터 fetch가 부수 효과로 발생합니다.

useMemo와 useEffect의 차이점

특징 useMemo useEffect
주요 목적 값 계산 결과를 메모이제이션하여 성능 최적화 부수 효과 처리(API 호출, DOM 조작 등)
실행 시점 컴포넌트 렌더링 시 (의존성 배열 값이 변경될 때만 실행) 렌더링 후 실행 (의존성 배열 값이 변경될 때 실행)
반환값 계산된 값 없음 (선택적으로 클린업 함수 반환)
의존성 배열 계산 결과에 영향을 주는 값 포함 부수 효과가 의존하는 값 포함
사용 사례 - 계산 비용이 높은 작업 최적화
- 필터링, 정렬 결과 저장
- 데이터 가져오기 (API 호출)
- DOM 업데이트
- 이벤트 리스너 추가/제거
주요 차이점 값 계산을 위한 것이며, 렌더링과 관련된 작업에는 관여하지 않음 렌더링 이후 발생하는 작업이나 클린업 작업에 적합

비교 예제

useMemo로 필터링된 값 계산

const filteredItems = useMemo(() => {
  return items.filter(item => item.isActive);
}, [items]);
  • 렌더링과 무관한 계산 작업(필터링된 배열) 최적화.

useEffect로 데이터 가져오기

useEffect(() => {
  fetch("/api/items")
    .then(res => res.json())
    .then(data => setItems(data));
}, []);
  • 렌더링 이후 발생하는 부수 효과(데이터 가져오기).

요약

  1. useMemo: 값 계산과 관련된 최적화. 렌더링 프로세스에서 계산을 최소화.
  2. useEffect: 렌더링 이후 실행되는 작업 관리. 외부와의 상호작용(API 호출, 이벤트 리스너 등)에 적합.

useMemo는 "값 계산을 효율적으로", useEffect는 **"렌더링 후 부수 작업 처리"**를 위해 사용됩니다. 🚀

 
 
 
Q2.

나의 말:

어떤 값이 바뀌면, 그 바뀐 값을 가지고 다시 연산을 해야 하는 경우에는,

어떤 값을 의존성 배열에 걸고 useMemo를,
 

어떤 값이 바뀌었을 때, 특정 동작을 하게 설정하려면 useEffect를 쓴다고 생각하면 될까?

 
 
 
A2.

ChatGPT의 말:

 

네, 맞습니다! 말씀하신 방식으로 useMemo와 useEffect를 구분하면 적절합니다. 이를 조금 더 구체적으로 설명하자면 다음과 같습니다:


1. useMemo의 활용

  • 목적: 값을 계산하고, 계산 결과를 메모이제이션하여 성능을 최적화.
  • 의존성 배열: 계산에 영향을 주는 값을 포함.
  • 언제 사용하나?
    • 어떤 값이 바뀌었을 때, 그 값을 기반으로 새로운 값을 계산해야 하는 경우.
    • 계산 결과를 재사용해서 불필요한 재계산을 방지하려는 경우.

예제: 값이 바뀌면 계산

const filteredItems = useMemo(() => {
  console.log("Filtering items...");
  return items.filter(item => item.isActive);
}, [items]); // 'items'가 바뀌면 필터링 작업을 다시 수행
  • 설명:
    • items가 변경될 때만 useMemo가 실행되어 filteredItems를 재계산.
    • 만약 items가 변경되지 않으면 이전의 계산 결과를 반환하여 불필요한 필터링 작업을 방지.

2. useEffect의 활용

  • 목적: **값이 바뀌었을 때 특정 동작(부수 효과)**을 수행.
  • 의존성 배열: 효과 실행 조건이 되는 값 포함.
  • 언제 사용하나?
    • 특정 값이 바뀌었을 때 어떤 행동을 트리거하려는 경우.
    • 예: API 호출, DOM 조작, 타이머 설정, 이벤트 리스너 등록 등.

예제: 값이 바뀌면 동작 수행

useEffect(() => {
  console.log("Count has changed:", count);
}, [count]); // 'count'가 바뀔 때마다 로그를 출력
  • 설명:
    • count가 변경될 때마다 로그 메시지를 출력.
    • 이처럼 값의 변화에 반응하여 동작을 수행할 때 useEffect를 사용.

주요 차이점 요약

질문 useMemo useEffect
계산 vs 동작 특정 값을 계산해야 하는 경우 특정 동작(부수 효과)을 수행해야 하는 경우
의존성 배열의 의미 계산에 영향을 주는 값 동작을 트리거하는 값
결과 계산된 값 동작 수행 후 반환값 없음 (옵션으로 클린업 함수 반환 가능)
: 특정 값이 바뀌면 계산 배열을 필터링하거나 복잡한 연산을 최적화 값이 바뀌면 로그를 출력하거나 데이터를 새로 가져오기
: 값이 바뀌었을 때 행동 N/A 이벤트 리스너 추가, API 호출, DOM 조작

실제 활용 예제 비교

1. useMemo: 값 계산 최적화

const sortedItems = useMemo(() => {
  console.log("Sorting items...");
  return items.sort((a, b) => a.value - b.value);
}, [items]); // 'items'가 바뀌면 다시 정렬

return <div>{sortedItems.map(item => item.name)}</div>;
  • 설명: items가 변경될 때만 정렬을 수행. 정렬 결과를 재사용하여 성능 최적화.

2. useEffect: 값 변화에 따라 동작 수행

useEffect(() => {
  console.log("Fetching data because query changed...");
  fetch(`/api/data?query=${query}`)
    .then(res => res.json())
    .then(data => setData(data));
}, [query]); // 'query'가 바뀌면 데이터를 다시 가져오기

return <div>{data ? data.title : "Loading..."}</div>;
  • 설명: query가 변경될 때마다 데이터를 가져오는 동작 수행.

간단한 판단 기준

  • 값을 계산해서 메모이제이션하고 싶다면 useMemo:
    • "값 A가 바뀌면, 이 값을 기반으로 새로운 값 B를 계산해야 한다."
    • ex: 필터링, 정렬, 복잡한 계산 등.
  • 값이 바뀔 때 특정 동작을 실행하고 싶다면 useEffect:
    • "값 A가 바뀌면, 동작 X를 수행해야 한다."
    • ex: API 호출, DOM 조작, 이벤트 리스너 설정 등.

정리된 한 줄 정의

  • useMemo: 계산 결과를 반환합니다.
  • useEffect: 값의 변화에 따라 동작을 수행합니다.

이 기준을 기억하시면 상황에 따라 적절히 useMemo와 useEffect를 사용할 수 있습니다! 🚀

 
 
 
Q3.

나의 말:

짧은 문장으로 답해줘. useEffect는 반환값이 없는게 맞지?

 
 
 
A3.

ChatGPT의 말:

네, useEffect는 반환값이 없습니다. 다만 선택적으로 클린업 함수를 반환할 수 있습니다.

 

 

 
Q4.

 

나의 말:
짧은 문장으로 답해줘. 메모이제이션의 정확한 의미가 뭐야?
 
 
 
A4.
ChatGPT의 말:
메모이제이션비용이 큰 연산의 결과를 저장해 두고, 동일한 입력값이 다시 주어질 때 재계산 없이 저장된 결과를 반환하는 최적화 기술입니다.