숨참고 개발다이브

[React Native] flatlist의 콜백 옵션 (removeClippedSubviews, onScrollToIndexFailed) 본문

개발/React & React Native

[React Native] flatlist의 콜백 옵션 (removeClippedSubviews, onScrollToIndexFailed)

사라 Sarah 2024. 2. 28. 18:21
728x90

removeClippedSubviews

공식 문서

https://reactnative.dev/docs/flatlist#removeclippedsubviews

 

FlatList · React Native

A performant interface for rendering basic, flat lists, supporting the most handy features:

reactnative.dev

 

removeClippedSubviews 속성을 true로 설정하면 화면 영역 밖에 있는 컴포넌트들을 자동으로 메모리에서 삭제한다.

기본적으로 React Native의 리스트나 스크롤뷰는 화면에 보이지 않는 항목들도 메모리에 유지하는데, 스크롤 동작이 부드럽게 유지되도록 하기 위한 것이지만, 많은 양의 아이템이 있는 경우 메모리 소비가 커질 수 있다.

이때 removeClippedSubviews 속성을 사용하면 화면 밖으로 사라진 항목들을 메모리에서 제거하여 메모리 사용량을 줄일 수 있다.

 

하지만 removeClippedSubviews 옵션을 true로 설정할 때, 컨텐츠 누락과 같은 버그가 발생할 수 있다.

프로젝트 내에서 화면 진입 시 scrollToIndex를 호출하여 특정 페이지로 이동하는 경우, 안드로이드 환경에서 이전 페이지가 렌더가 제대로 일어나지 않는 버그가 발생했다.

 

이를 해결하기 위해 removeClippedSubviews={false} 로 설정하여 메모리를 소비하지만 렌더가 제대로 이루어지도록 처리했다.

 

 

728x90

 

onScrollToIndexFailed

onScrollToIndexFailed 콜백은 scrollToIndex 메서드를 사용하여 특정 인덱스로 스크롤 할 때 해당 인덱스로 스크롤할 수 없을 때 호출된다.

예를 들어, FlatList의 scrollToIndex 메서드를 사용하여 특정 인덱스로 스크롤을 시도하지만 해당 인덱스가 리스트에 없어서 스크롤이 실패한 경우에 이 콜백이 호출된다.

 

onScrollToIndexFailed(info: {
  index: number, // 스크롤을 시도한 인덱스
  highestMeasuredFrameIndex: number, // 측정된 가장 높은 인덱스
  averageItemLength: number // 평균 아이템 길이
})

 

제공되는 info 객체는 스크롤을 시도한 인덱스(index)와 현재 측정된 가장 높은 인덱스(highestMeasuredFrameIndex) 등의 정보를 포함한다. 이를 활용하여 스크롤 실패에 대응하는 로직을 작성할 수 있다.

 

 

onScrollToIndexFailed 가 없을 때 발생하는 에러

Invariant Violation: scrollToIndex should be used in conjunction with getItemLayout or onScrollToIndexFailed, otherwise there is no way to know the location of offscreen indices or handle failures.

 

 

해당 오류를 해결하기 위해 프로젝트 내 Flatlist에 다음과 같은 onScrollToIndexFailed 콜백을 설정해 주었다.

const onScrollToIndexFailed = (info: { index: number }) => {
	const timeout = setTimeout(() => {
      listRef.current?.scrollToIndex({ index: info.index, animated: true });
  }, 500);
};

 

 

300x250
Comments