React useEffect를 사용할 때 종속성 배열에 대한 이해

김현준·2024년 7월 9일
0

리액트 이모저모

목록 보기
11/27

React 프로젝트를 진행하다 보면 useEffect를 사용할 때 종속성 배열에 대해 정확히 이해하는 것이 매우 중요하다. 아래의 두 코드 예제는 useEffect의 종속성 배열 설정에 따라 작동 방식이 어떻게 달라지는지를 보여준다.

1번 코드

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { useRecoilValue } from "recoil";
import { charWindAndPickAtom } from "../../../atoms";

function CharacterInfo() {
  const { characterName } = useParams();
  const charWindAndPick = useRecoilValue(charWindAndPickAtom);
  const [pickNum, setPickNum] = useState(0);
  let newCharWindAndPick = [...charWindAndPick];

  useEffect(() => {
    const pickRankIndex = newCharWindAndPick
      .sort((a, b) => Number(a.pickRate) - Number(b.pickRate))
      .findIndex((item) => item.characterName === characterName);
    setPickNum(pickRankIndex);
  }, [newCharWindAndPick, setPickNum]);
}

2번 코드

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { useRecoilValue } from "recoil";
import { charWindAndPickAtom } from "../../../atoms";

function CharacterInfo() {
  const { characterName } = useParams();
  const charWindAndPick = useRecoilValue(charWindAndPickAtom);
  const [pickNum, setPickNum] = useState(0);

  useEffect(() => {
    let newCharWindAndPick = [...charWindAndPick];
    const pickRankIndex = newCharWindAndPick
      .sort((a, b) => Number(a.pickRate) - Number(b.pickRate))
      .findIndex((item) => item.characterName === characterName);
    setPickNum(pickRankIndex);
  }, [charWindAndPick, setPickNum]);
}

차이점 및 원인

1번 코드와 2번 코드의 가장 큰 차이점은 useEffect의 종속성 배열과 newCharWindAndPick의 정의 위치이다.

  • newCharWindAndPick의 정의 위치:

    • 1번 코드에서는 newCharWindAndPick이 useEffect 바깥에 정의되어 있다.
      이는 useEffect가 실행될 때마다 새로운 배열이 생성되지 않도록 보장한다.

    • 2번 코드에서는 newCharWindAndPick이 useEffect 내부에 정의되어 있다.
      이는 charWindAndPick이 변경될 때마다 useEffect가 실행되고 새로운 배열이 생성된다.

  • useEffect의 종속성 배열:

  • 1번 코드에서는 newCharWindAndPick과 setPickNum을 종속성 배열에 포함하여, 이 값들이 변경될 때마다 useEffect가 실행된다.

  • 2번 코드에서는 charWindAndPick과 setPickNum을 종속성 배열에 포함하여, 이 값들이 변경될 때마다 useEffect가 실행된다.

결과

2번 코드에서는 characterName이 변경되어도 useEffect가 재실행되지 않기 때문에 pickNum이 업데이트되지 않는다.
반면에, 1번 코드는 characterName이 변경될 때 newCharWindAndPick이 변경되면서 useEffect가 재실행되어 pickNum이 올바르게 업데이트된다.

해결 방법

2번 코드의 useEffect 종속성 배열에 characterName을 추가하고, newCharWindAndPick을 useEffect 바깥으로 이동하여 한 번만 정의되도록 해야 한다.

수정된 2번 코드

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { useRecoilValue } from "recoil";
import { charWindAndPickAtom } from "../../../atoms";

function CharacterInfo() {
  const { characterName } = useParams();
  const charWindAndPick = useRecoilValue(charWindAndPickAtom);
  const [pickNum, setPickNum] = useState(0);

  useEffect(() => {
    let newCharWindAndPick = [...charWindAndPick];
    const pickRankIndex = newCharWindAndPick
      .sort((a, b) => Number(a.pickRate) - Number(b.pickRate))
      .findIndex((item) => item.characterName === characterName);
    setPickNum(pickRankIndex);
  }, [charWindAndPick, characterName, setPickNum]);
}

이렇게 하면 characterName이 변경될 때마다 useEffect가 재실행되어 pickNum이 올바르게 업데이트된다.

profile
기록하자

0개의 댓글

관련 채용 정보