useEffect 의존성 배열 이슈

January·2023년 9월 1일
0

Frontend

목록 보기
31/31

팀플하면서 발생한 이슈를 기록해보자!

함수 중복 실행

우선 코드를 보자

const Test = () => {
  const [ab, setAb] = useState(0);

  const numberUp = () => {
    setAb((prev) => prev + 1);
  };

  const friend = () => {
    numberUp();
  };

  useEffect(() => {
    friend();
  }, [friend]);
}

보기만 해도 예상이 간다.
실 상황에서는 이것보다 좀 더 고민을 해야했다. IntersectionObserver() 로직이기 때문이다.

const callbackObserver = (entries: IntersectionObserverEntry[]) => {
    const entry = entries[0];
    if (entry.isIntersecting) {
      callback();
    }
  };

entry.isIntersecting은 타겟이 뷰포트와 교차됐는지를 알려준다. 교차가 되지 않으면 callback을 호출하지 않는다. 이 부분이 위에 있는.. 결과가 뻔한 코드 이슈를 햇갈리게 했다.
구현한 내용을 말하자면 api로 리스트 응답 받는 것이다. 그래서 무한 호출이 될때 응답 온 리스트가 추가되면서 타겟이 뷰포트 아래로 내려가니까 callback이 멈추고 IntersectionObserverEntry 초기화 됐다. 이 부분이 날 햇갈리게 했다.

해결

리렌더링과 IntersectionObserverEntry option 두가지 중에 하나가 원인일거라고 생각하면서 흐름을 쫓아가봤다. 리렌더링을 발생시키는 주체는 state였는데 state update를 하는건 useEffect였고 useEffect를 실행하는건 어느 함수였다.

useEffect 의존성 배열에 함수 대신 이 기능의 핵심 state인 pageNumber를 넣고서 해결해버렸다...가 아닌 해결 당했다

그리고서 생각해봤는데 useEffect가 동작시키는 로직에는 한개 이상의 state를 변화시킨다. 그럼 함수도 여러번 재생성되겠지? 그럼 useEffect도 뒤이어서 실행되겠지? 오잉?

그리고 의존성 배열에 들어가 있던 함수는 이 기능, 로직에 함수 변화를 감지해야하것이 필요하지 않았다.

결론

useEffect에서 실행되는 로직에 변화를 감지하고 update해서 실행되야한다면 그 주체를 찾고 의존성 배열에 넣어주자. 리렌더링을 유발하는 여러 주체가 있는지 고려하고 의존성 배열과 실행 요건을 생각하자

0개의 댓글