useFocusEffect 및 setInterval

devAnderson·2023년 1월 2일
0

Error Handling

목록 보기
7/11

1. Background

기존 사용되던 배너에 오류가 발생해서 해결해야 하는 상황이 발생했다.

내부 코드를 뜯어보고 setInterval이 사용되던 것을 확인한 나는 너무 쉽게 "이거 그냥 clear 제대로 안해서구만... 제대로 하게 만들면 되겠네" 라고 생각하고 넘겨버렸는데,

생각보다 좀 여러가지 변수가 많았고, 이로 인해서 고통받은 내용을 기록한다.


a. useFocusEffect

항상 이런 글을 쓸 때마다 생각하는 것은 "공식 문서를 좀 제대로 읽자" 라는 부분이다 (...)

공식 문서 상에서 해당 훅을 아래와 같이 설명하고 있다.

해당 스크린이 포커싱이 되었을때 발생하는 훅. 또한 리랜더링이 발생해도 호출됨. 따라서, useCallback으로 해당 함수객체를 메모해두지 않으면 리랜더링이 발생할 때마다 계속 호출될 것임. useCallback으로 감싸두면 dependency가 변동될 때에 이에 대응하여 호출될 것.


사실 저 위에 있는 문구가 제일 중요하다. 리랜더링에도 발생한다는 것.
그래서 useCallback으로 함수를 넣어주고, dependency를 설정해서 해당 환경이 업데이트 되야할지 안되야 할지를 확정해주는 것이다.

useCallback은 dependency에 존재하는 값이 변동되면 인자로 받은 함수를 재정의하고 호출한다.

즉, dependency가 빈배열이면 변경점이 없으므로 호출되지 않는다.

여기서 중요한 부분은, useCallback이 재정의되면서 내부의 변수들은 dependency에 정의된 내용이면 재정의되지 않는다.

여기서 나는 setInterval 함수 안에 정의되고 있는 intervalHandler 가 과연 재정의되는지 아닌지가 궁금했다.

만약 currentIndex 를 dependency로 넣고, 호출을 해보면

console.log(intervalIdRef.current)는 계속 초깃값인 null이 찍힌다.

그 말인 즉슨, useCallback의 함수 재정의 기준은 ref값이 포함되지 않는다는 소리가 된다.

반대로, currentIndex는 디펜던시 안에 들어가 있기 때문에 해당 값은 초기화된다.

그러면

intervalHandler 내부에 currentIndex를 쓰고 있기 때문에 해당 함수는 과연 재정의되는 것일까?

정답은 아니다이다.

다만, 해당 함수가 선언되어있는 렉시컬한 환경은 리랜더링에 의해서 재정의되기 때문에, 해당 함수는 새롭게 만들어진 버추얼 돔의 지역 값을 사용하게 된다.

해당 콘솔에서도 볼 수 있듯이, 내부 current에서 확인되는 intervalIdRef.current는 계속해서 최신 렉시컬 환경의 값을 가져오고 있다.


결론

여차저차 이것저것 실험하면서 알게 된 내용들을 정리해보았다. 요약하자면 아래와 같다

  1. useFocusEffect는 리랜더링이 발생하면 호출된다
  2. useCallback의 디펜던시에 있는 내용이 변동되면 인자로 받은 함수가 재정의되면서 변동된 값에 해당하는 내용이 최신화되어 호출된다.
  3. 디펜던시에 정의되지 않은 값은 기존 메모리 주솟값을 그대로 사용한다.
profile
자라나라 프론트엔드 개발새싹!

0개의 댓글