Skip to main content
Version: Next

VirtualizedList

<FlatList><SectionList> 컴포넌트는 더 편리하고 잘 문서화되어 있다. 이 컴포넌트들은 FlatList가 제공하는 것보다 더 많은 유연성이 필요할 때 사용한다. 예를 들어, 일반 배열 대신 불변 데이터를 사용해야 하는 경우에 적합하다.

가상화는 활성 아이템의 유한한 렌더링 윈도우를 유지하고, 렌더링 윈도우 밖의 아이템을 적절한 크기의 빈 공간으로 대체함으로써 대형 리스트의 메모리 소비와 성능을 크게 개선한다. 윈도우는 스크롤 동작에 따라 적응하며, 아이템은 보이는 영역에서 멀리 떨어진 경우 낮은 우선순위로(실행 중인 상호작용 이후에) 점진적으로 렌더링된다. 반면, 보이는 영역에 가까운 경우 높은 우선순위로 렌더링되어 빈 공간을 최소화한다.

예제


몇 가지 주의사항:

  • 렌더링 윈도우를 벗어나 스크롤되는 콘텐츠의 내부 상태는 보존되지 않는다. 모든 데이터를 아이템 데이터나 Flux, Redux, Relay 같은 외부 저장소에 저장해야 한다.

  • 이 컴포넌트는 PureComponent이기 때문에 props가 얕은 비교(Shallow Equal)에서 동일하면 리렌더링하지 않는다. renderItem 함수가 의존하는 모든 데이터를 extraData와 같은 프로퍼티로 전달해야 한다. 그렇지 않으면 UI가 업데이트되지 않을 수 있다. 여기에는 data 프로퍼티와 부모 컴포넌트의 상태도 포함된다.

  • 메모리를 제한하고 부드러운 스크롤을 위해 콘텐츠는 비동기적으로 오프스크린에서 렌더링된다. 이는 스크롤 속도가 채우기 속도보다 빠를 경우 잠깐 빈 화면이 보일 수 있다는 의미다. 이는 각 애플리케이션의 요구에 맞게 조정할 수 있는 트레이드오프이며, 내부적으로 이를 개선하기 위해 노력 중이다.

  • 기본적으로 리스트는 각 아이템의 key 프로퍼티를 찾아 React 키로 사용한다. 또는 커스텀 keyExtractor 프로퍼티를 제공할 수 있다.


참조

Props

ScrollView Props

ScrollView Props를 상속받는다.

data

getItemgetItemCount에 전달되는 불투명한 데이터 타입으로, 항목을 검색하는 데 사용된다.

타입
any

필수
getItem

tsx
(data: any, index: number) => any;

어떤 종류의 데이터 블롭에서 항목을 추출하기 위한 일반적인 접근자이다.

타입
function

필수
getItemCount

tsx
(data: any) => number;

데이터 블롭에 포함된 항목의 수를 결정한다.

타입
함수

필수
renderItem

tsx
(info: any) => ?React.Element<any>

data에서 가져온 항목을 리스트로 렌더링한다.

타입
함수

CellRendererComponent

CellRendererComponentrenderItem이나 ListItemComponent로 렌더링된 cell이 기본 ScrollView에 배치될 때, 이를 감싸는 방식을 커스텀하게 정의할 수 있도록 한다. 이 컴포넌트는 cell 내부에서 발생하는 변경 사항을 VirtualizedList에 알리는 이벤트 핸들러를 반드시 받아들여야 한다.

타입
React.ComponentType<CellRendererProps>

ItemSeparatorComponent

각 아이템 사이에 렌더링되지만 맨 위나 맨 아래에는 렌더링되지 않는다. 기본적으로 highlightedleadingItem 프로퍼티가 제공된다. renderItemseparators.highlight/unhighlight를 제공하며, 이를 통해 highlighted 프로퍼티를 업데이트할 수 있다. 또한 separators.updateProps를 사용해 커스텀 프로퍼티를 추가할 수도 있다. React 컴포넌트(예: SomeComponent)나 React 엘리먼트(예: <SomeComponent />)로 사용할 수 있다.

타입
컴포넌트, 함수, 엘리먼트

ListEmptyComponent

리스트가 비어 있을 때 렌더링된다. React 컴포넌트(예: SomeComponent)나 React 엘리먼트(예: <SomeComponent />)를 사용할 수 있다.

타입
컴포넌트, 엘리먼트

ListItemComponent

각 데이터 항목을 렌더링할 때 사용하는 엘리먼트이다. React 컴포넌트 클래스나 렌더 함수로 정의할 수 있다.

타입
컴포넌트, 함수

ListFooterComponent

모든 아이템 하단에 렌더링된다. React 컴포넌트(예: SomeComponent)나 React 엘리먼트(예: <SomeComponent />)로 사용할 수 있다.

타입
컴포넌트, 엘리먼트

ListFooterComponentStyle

ListFooterComponent의 내부 View를 스타일링한다.

타입필수 여부
ViewStyleProp아니오

ListHeaderComponent

모든 아이템 상단에 렌더링되는 컴포넌트이다. React 컴포넌트(예: SomeComponent)나 React 엘리먼트(예: <SomeComponent />)로 정의할 수 있다.

타입
컴포넌트, 엘리먼트

ListHeaderComponentStyle

ListHeaderComponent 내부 View에 대한 스타일링을 정의한다.

타입
View 스타일

debug

debug는 사용법과 구현 과정을 디버깅하는 데 도움이 되는 추가 로깅과 시각적 오버레이를 활성화한다. 하지만 성능에 상당한 영향을 미칠 수 있다.

타입
boolean

disableVirtualization

더 이상 사용되지 않음. 가상화는 성능과 메모리 최적화를 크게 향상시키지만, 렌더링 윈도우 바깥에 있는 React 인스턴스를 완전히 언마운트한다. 디버깅 목적으로만 이 기능을 비활성화해야 한다.

타입
boolean

extraData

리스트를 리렌더링하도록 지시하기 위한 마커 프로퍼티이다. (PureComponent를 구현했기 때문) renderItem, Header, Footer 등 함수가 data 프로퍼티 외부의 어떤 것에 의존한다면, 이곳에 넣고 불변하게 처리한다.

타입
any

getItemLayout

tsx
(
data: any,
index: number,
) => {length: number, offset: number, index: number}
타입
함수

horizontal

true로 설정하면 아이템을 세로로 쌓는 대신 가로로 나란히 배치한다.

타입
boolean

initialNumToRender

초기에 렌더링할 아이템의 수를 지정한다. 이 값은 화면을 채우기에 충분한 수준으로 설정해야 하지만, 너무 많지 않도록 주의한다. 이 아이템들은 스크롤 상단 이동 시 성능을 향상시키기 위해 윈도우 렌더링 과정에서 절대 언마운트되지 않는다.

타입기본값
number10

initialScrollIndex

첫 번째 항목부터 시작하는 대신, initialScrollIndex에서 시작한다. 이 설정은 첫 번째 initialNumToRender 항목을 항상 렌더링하는 "맨 위로 스크롤" 최적화를 비활성화하고, 초기 인덱스부터 항목을 즉시 렌더링한다. 이 기능을 사용하려면 getItemLayout을 구현해야 한다.

타입
number

inverted

스크롤 방향을 반전시킨다. -1 스케일 변환을 사용한다.

타입
boolean

keyExtractor

tsx
(item: any, index: number) => string;

주어진 아이템과 인덱스에 대해 고유한 키를 추출하는 데 사용한다. 이 키는 캐싱과 아이템 재정렬을 추적하기 위한 React 키로 활용된다. 기본 추출기는 item.key, item.id를 차례로 확인하고, 둘 다 없는 경우 React와 마찬가지로 인덱스를 사용한다.

타입
함수

maxToRenderPerBatch

한 번에 렌더링할 항목의 최대 개수를 지정한다. 한 번에 많은 항목을 렌더링하면 화면 채우기 속도가 빨라지지만, 버튼 터치나 기타 상호작용에 대한 응답성이 떨어질 수 있다. 렌더링 작업이 사용자 입력 처리에 영향을 미칠 수 있기 때문이다.

타입
number

onEndReached

스크롤 위치가 리스트의 논리적 끝에서 onEndReachedThreshold 이내로 접근할 때 한 번 호출된다.

타입
(info: {distanceFromEnd: number}) => void

onEndReachedThreshold

리스트의 끝에서 얼마나 떨어져 있어야 onEndReached 콜백이 트리거되는지를 결정한다. 이 값은 리스트의 보이는 길이 단위로 측정된다. 예를 들어, 0.5로 설정하면 컨텐츠의 끝이 리스트의 보이는 길이의 절반 이내에 있을 때 onEndReached가 트리거된다.

타입기본값
number2

onRefresh

tsx
() => void;

이 함수를 제공하면 "당겨서 새로고침(Pull to Refresh)" 기능을 위한 표준 RefreshControl이 추가된다. 이때 refreshing 속성도 올바르게 설정해야 한다.

타입
function

onScrollToIndexFailed

tsx
(info: {
index: number,
highestMeasuredFrameIndex: number,
averageItemLength: number,
}) => void;

아직 측정되지 않은 인덱스로 스크롤을 시도했을 때 실패하는 경우를 처리한다. 일반적으로 직접 오프셋을 계산하여 scrollTo를 호출하거나, 가능한 한 스크롤한 후 더 많은 아이템이 렌더링된 뒤 다시 시도하는 것을 권장한다.

타입
함수

onStartReached

리스트의 논리적 시작점에서 onStartReachedThreshold 이내로 스크롤 위치가 들어오면 한 번 호출된다.

타입
(info: {distanceFromStart: number}) => void

onStartReachedThreshold

리스트의 시작 부분에서 콘텐츠의 시작 지점까지 얼마나 떨어져 있어야 onStartReached 콜백이 트리거되는지를 나타낸다. 이 값은 리스트의 보이는 길이 단위로 측정된다. 예를 들어, 값이 0.5라면 콘텐츠의 시작 지점이 리스트의 보이는 길이의 절반 이내에 있을 때 onStartReached가 트리거된다.

타입기본값
number2

onViewableItemsChanged

행의 가시성이 변경될 때 호출된다. 가시성은 viewabilityConfig 속성으로 정의된다.

타입
(callback: {changed: ViewToken[], viewableItems: ViewToken[]}) => void

persistentScrollbar

타입
bool

progressViewOffset

로딩 인디케이터가 올바르게 표시되도록 오프셋이 필요할 때 이 값을 설정한다.

타입
number

refreshControl

커스텀 새로고침 컨트롤 엘리먼트. 이 속성을 설정하면 내장된 기본 <RefreshControl> 컴포넌트를 덮어쓴다. 이 경우 onRefreshrefreshing 속성은 무시된다. 이 기능은 수직 방향의 VirtualizedList에서만 작동한다.

타입
엘리먼트

새로운 데이터를 갱신(refresh)하는 동안 기다릴 때 이 값을 true로 설정한다.

타입
boolean

removeClippedSubviews

이 옵션은 큰 목록의 스크롤 성능을 향상시킬 수 있다.

참고: 특정 상황에서 버그(콘텐츠 누락)가 발생할 수 있으므로 주의해서 사용해야 한다.

타입
boolean

renderScrollComponent

tsx
(props: object) => element;

커스텀 스크롤 컴포넌트를 렌더링한다. 예를 들어, 스타일이 다른 RefreshControl을 적용할 수 있다.

타입
함수

viewabilityConfig

ViewabilityHelper.js 파일에서 플로우 타입과 추가 문서를 확인할 수 있다.

타입
ViewabilityConfig

viewabilityConfigCallbackPairs

ViewabilityConfigonViewableItemsChanged의 쌍으로 이루어진 리스트다. 특정 ViewabilityConfig의 조건이 충족되면, 해당하는 onViewableItemsChanged가 호출된다. 자세한 플로우 타입과 추가 문서는 ViewabilityHelper.js를 참고한다.

타입
ViewabilityConfigCallbackPair 배열

updateCellsBatchingPeriod

화면에서 멀리 떨어진 아이템을 렌더링할 때, 낮은 우선순위 렌더링 배치 간의 시간 간격을 설정한다. maxToRenderPerBatch와 유사하게 렌더링 속도와 반응성 간의 균형을 조절한다.

타입
number

windowSize

화면에 보이는 영역 외부에서 렌더링할 최대 항목 수를 결정한다. 단위는 화면 길이 기준이다. 예를 들어, 리스트가 화면을 가득 채우는 경우, 기본값인 windowSize={21}은 현재 보이는 화면 영역과 뷰포트 상하로 각각 10개 화면 분량의 항목을 추가로 렌더링한다. 이 값을 줄이면 메모리 사용량이 감소하고 성능이 개선될 수 있지만, 빠르게 스크롤할 때 렌더링되지 않은 빈 공간이 잠시 보일 가능성이 높아진다.

타입
number

메서드

flashScrollIndicators()

tsx
flashScrollIndicators();

getScrollableNode()

tsx
getScrollableNode(): any;

getScrollRef()

tsx
getScrollRef():
| React.ElementRef<typeof ScrollView>
| React.ElementRef<typeof View>
| null;

getScrollResponder()

tsx
getScrollResponder () => ScrollResponderMixin | null;

기본 스크롤 응답자에 대한 핸들을 제공한다. this._scrollRefScrollView가 아닐 수도 있기 때문에, 해당 메서드를 호출하기 전에 getScrollResponder에 응답하는지 확인해야 한다.

scrollToEnd()

tsx
scrollToEnd(params?: {animated?: boolean});

컨텐츠의 끝으로 스크롤한다. getItemLayout prop이 없으면 버벅거릴 수 있다.

인자:

이름타입
paramsobject

유효한 params 키는 다음과 같다:

  • 'animated' (boolean) - 스크롤 시 애니메이션을 적용할지 여부. 기본값은 true이다.

scrollToIndex()

tsx
scrollToIndex(params: {
index: number;
animated?: boolean;
viewOffset?: number;
viewPosition?: number;
});

유효한 params는 다음과 같이 구성된다:

  • 'index' (number). 필수.
  • 'animated' (boolean). 선택 사항.
  • 'viewOffset' (number). 선택 사항.
  • 'viewPosition' (number). 선택 사항.

scrollToItem()

tsx
scrollToItem(params: {
item: ItemT;
animated?: boolean;
viewOffset?: number;
viewPosition?: number;
);

params에 유효한 값은 다음과 같다:

  • 'item' (Item). 필수.
  • 'animated' (boolean). 선택 사항.
  • 'viewOffset' (number). 선택 사항.
  • 'viewPosition' (number). 선택 사항.

scrollToOffset()

tsx
scrollToOffset(params: {
offset: number;
animated?: boolean;
});

리스트에서 특정 콘텐츠 픽셀 오프셋으로 스크롤한다.

offset 파라미터는 스크롤할 오프셋을 지정한다. horizontaltrue인 경우, 오프셋은 x값을 의미한다. 그 외의 경우에는 오프셋이 y값을 나타낸다.

animated 파라미터(기본값은 true)는 스크롤 시 애니메이션을 사용할지 여부를 결정한다.