트러블슈팅

setState 로 인한 useEffect에서 일어나는 무한렌더링

노엠디엔 2023. 12. 1. 11:34

getGroupMemberFetch함수는 api 요청을 통해 가져온 결과를 바로 setState를 통해 상태를 업데이트한다

해당 함수를 useEffect내에서 함수 호출을 통해 사용하니 무한렌더링이 발생해 터미널이 요동치기 시작했다.

일단 문제가 발생하는 순서의 원인은 이렇다.

  1. getGroupMemberFetch 함수 내에서 setUserGroups를 호출하여 userGroups 상태를 업데이트.
  2. userGroups가 의존성 배열에 포함되어 있기 때문에 상태가 업데이트되면 useEffect가 다시 실행.
  3. 다시 실행된 useEffect에서 getGroupMemberFetch 함수를 호출하게 되고, 이로 인해 다시
    setUserGroups가 호출되어 상태가 업데이트.
  4. 상태가 업데이트되면 다시 useEffect가 실행되고, 이 과정이 반복되면서
    무한 렌더링이 발생해 살려달라고 함.

코드를 작성하면서도 뭔가 심상치 않을 것 같다는 예상은 했지만 오랜만에 무한 렌더링이 발생한 김에
공부할 겸 기록을 남겨보려고 함.

 

내가 생각하는 해결 방법은 2가지였다.

  1. useEffect 에 의존성 배열에서 getGroupMemberFetch함수를 제거.
  2. useEffct에서 getGroupMemberFetch를 .then .catch를 사용해(promise) 비동기 처리를 통해 setState 처리

 첫번째 방법은 useEffect에게 너만 모르면 다 해결됨!을 시전 즉 useEffect에게 거짓말을 하는 것이니 

나중에 문제가 있을 것 같다. - 의존성배열에서도 경고를 뱉는다.

 

두번째 방법을 사용해 해당 문제를 해결할 수 있었지만 결국 가독성의 문제도 조금 생기고

getGroupMemberFetch 함수 자체가 이미 비동기 처리를 통해 try, catch문을 사용하는데

이 방법은 쓸모없는 포장지를 여러번 감싸는 느낌이 들었다.

 

더이상의 해결방법은 떠오르지않아서 일단 then, catch문을 사용하여 해결하였다.

이렇게 되는데 보기 불편해서 나는  useEffect내에서 setState를 처리할 수 있게 비동기 처리용 함수를 만들었다.

이런식으로 결국 또 포장지를 하나 더 만든 느낌이였다. (연말 특집 선물 포장지이다)

내가 해결한 방법이 분명 좋은 방법이라고 할 순 없을 것 같다.. 다른 방법이 있을 것이다 분명;;

해결 방법을 찾는다면 또 다시 기록을 남겨야겠다.

 

이번 트러블 슈팅은 react-query왜 사용하는지 정말 알 수 있는 문제였던 것 같다. 

또한 useEffect내에서 발생하는 무한렌더링에 대해서도 좀 더 공부를 해봐야겠다

새롭게 알게된 건 useEffect 의존성 배열에 함수를 추가시 useEffect는 얕은 비교를 개념으로 사용한다?고 함

결국 렌더링 시 마다 함수를 계속 참조하게 되므로 무한 렌더링 발생!

그렇기 때문에 useCallback을 사용해서 해당 함수를 재생성하지 않게 끔 만들어 무한렌더링을 방지하는것!

 

참고 블로그:

https://velog.io/@summereuna/%EB%A6%AC%EC%95%A1%ED%8A%B8-useEffect-%EB%AC%B4%ED%95%9C-%EB%A3%A8%ED%94%84-%ED%83%88%EC%B6%9C%ED%95%98%EA%B8%B0