[에러로그] 사이드프로젝트 리팩토링의 날

릿·2023년 2월 14일
0

디버깅

목록 보기
2/2

0. 서두

나는 굳이 이걸 이렇게까지 나눠서 뎁스가 깊어지는 게 맞나? -라고 생각하는 1인이라 한꺼번에 코드를 짜놓고 최후의 최후까지 컴포넌트 나누기를 미루는 타입이다.
(물론 큰 틀은 나누고, 자잘한 건 추후에 나누고 있다.)
근데 요새 제로초님 강의를 보고 있는데 조금 반성도 되고, 협업하는 팀에게도 미안한 마음이 들어서 오늘은 컴포넌트 나누기 + 리팩토링을 해볼까 한다.

1. 이벤트리스너 함수들 useCallback으로 감싸주기


이 정도야 뭐, 순조롭다.
주의할 것은 함수 내부에 쓰인 state가 업데이트 될 때마다 함수도 업데이트 되도록 디펜던시를 꼭 넣어줄 것!

2. 날짜배열 생성로직 커스텀훅으로 빼기

프로젝트에서 오늘 날짜 기준으로 + 8일을 배열에 넣어서 버튼으로 뿌려주고 있다.
해당 부분을 주석처리 해도 딱히 에러나는 부분이 없어서 완전히 분리해주기로 한다.

그리고 원래 파일에 import를 해서 잘 가지고 오는지 확인해보자.


useEffect에 transformDate를 호출해본다.


ㅎ...

1) 디버깅: Invalid hook call.

Invalid hook call이 뜨는 이유는 세가지다.

(1) Mismatching Versions of React and React DOM

react-dom이 v16.8.0보다 낮으면 hooks을 사용할 수 없음

(2) Breaking the Rules of Hooks

hooks함수를 호출할 때 컴포넌트 최상위에서 호출해야 함

(3) Duplicate React

npm ls react를 해서 react가 혹시 두개 깔려있는지 확인 할 것

(출처: https://pimpdevelop.tistory.com/14)

내 경우엔 2번이었는데 사실 커스텀훅이라고 만든 건 아니지만 이미 리액트는 커스텀훅이라고 인식한 것 같았고 그걸 useEffect에서 호출하니 이런 일이 생기는 거였다...


그래서 이렇게 useState보다 높이 호출해주고 useEffect에서 sevenDayArr를 호출해봤다.


이건 뭐 하도 많이 본 에러라 놀랍지도 않다.
아마 리렌더 할 때마다 계속 transformDate를 호출하고 있어서 그런 것 같다.

2) 디버깅: Too many re-renders.

(1) useMemo를 사용해본다.

AppointmentDate로 TODAY상수를 옮기고 transformDate의 매개변수로 넣어준 뒤, 디펜던시에 TODAY를 넣어주었다.

const sevenDayArr = useMemo(() => transformDate(TODAY), [TODAY]);


'훅스 안에 커스텀훅 호출 하지말라니까!'.jpg

그냥 마음잡고 구글링을 해본다.

(2) 리액트의 렌더링 조건

  1. state 변경이 있을 때
  2. 부모 컴포넌트가 렌더링 될 때
  3. 새로운 props가 들어올 때
  4. shouldComponentUpdate 에서 true가 반환 될 때
  5. forceUpdate 가 실행 될 때
(출처: https://velog.io/@rxxdo/Error-Too-many-re-renders.-%EC%97%90%EB%9F%AC%ED%95%B4%EA%B2%B0)

...음, 조금 더 찾아보자.

(3) stack overflow답변

커스텀훅을 불러오기만 했을 뿐인데 무한루프에 빠지는 이유

  1. 컴포넌트가 커스텀훅을 호출한다.
  2. 커스텀훅은 useState의 set함수를 호출한다.
  3. useState를 통해 useState의 value업데이트를 트리거 한다.
  4. 이 경우, 커스텀훅이 두번째로 실행된다. (현재 커스텀훅 및 현재 렌더가 완료된 후)
  5. 이는 리렌더를 트리거한다. (다시 1단계로 돌아가 무한루프에 빠짐)

이 문제에 대한 해결책은 실제로 필요한 경우에만 커스텀훅 state를 업데이트 하는 것이다.

(출처: https://stackoverflow.com/questions/69890449/too-many-re-renders-when-using-custom-hook & Thanks to 파파고❤️)

그래서 커스텀훅이 값이 그대로일 경우, 리렌더링 되지 않도록 하는 방법이 필요한 것 같다.

3) 디버깅: Should have a queue.

커스텀훅을 호출한 후, console부분을 주석처리하니 생긴 오류였다. 해결방안은 2번과 비슷한 것 같다.
그래서 커스텀훅의 연산부분을 useEffect로 감싸준 후, TODAY값이 바뀔 때만 리렌더링 되도록 했다.

다행이도 잘 받아오고 있음!

근데 넌 뭐냐?...

아주 어이없는 에러였다.
커스텀훅 불러올 때 대괄호가 빠져서 그런 거였음.

// before
const transformDateArr = transformDate();

// after
const [transformDateArr] = transformDate();

무사해결!

4) 디버깅: 커스텀훅 데이터 받아오기 부분 코드변경


아, 약간의 문제가 생겼다. 커스텀훅에서 빈 배열이 들어온다ㅠ

커스텀훅에서 콘솔을 찍어보니 데이터는 제대로 나가고 있는 걸 확인할 수 있었다.

커스텀훅 호출부에서도 잘 불러오는 걸 확인할 수 있었다.

useEffect의 디펜던시에 sevenDayArr를 추가해주니 정상적으로 데이터가 나왔다. 생각보다 간단했음!

아참, 커스텀훅이니까 훅이름 앞에 use를 붙여주었다ㅎ
이제 진짜 완료!

profile
항상 재밌는 뭔가를 찾고 있는 프론트엔드 개발자

0개의 댓글