VirtualizedList
<FlatList>
와 <SectionList>
컴포넌트는 더 편리하고 잘 문서화되어 있다. 이 컴포넌트들은 FlatList
가 제공하는 것보다 더 많은 유연성이 필요할 때 사용한다. 예를 들어, 일반 배열 대신 불변 데이터를 사용해야 하는 경우에 적합하다.
가상화는 활성 아이템의 유한한 렌더링 윈도우를 유지하고, 렌더링 윈도우 밖의 아이템을 적절한 크기의 빈 공간으로 대체함으로써 대형 리스트의 메모리 소비와 성능을 크게 개선한다. 윈도우는 스크롤 동작에 따라 적응하며, 아이템은 보이는 영역에서 멀리 떨어진 경우 낮은 우선순위로(실행 중인 상호작용 이후에) 점진적으로 렌더링된다. 반면, 보이는 영역에 가까운 경우 높은 우선순위로 렌더링되어 빈 공간을 최소화한다.
예제
- TypeScript
- JavaScript
몇 가지 주의사항:
-
렌더링 윈도우를 벗어나 스크롤되는 콘텐츠의 내부 상태는 보존되지 않는다. 모든 데이터를 아이템 데이터나 Flux, Redux, Relay 같은 외부 저장소에 저장해야 한다.
-
이 컴포넌트는
PureComponent
이기 때문에props
가 얕은 비교(Shallow Equal)에서 동일하면 리렌더링하지 않는다.renderItem
함수가 의존하는 모든 데이터를extraData
와 같은 프로퍼티로 전달해야 한다. 그렇지 않으면 UI가 업데이트되지 않을 수 있다. 여기에는data
프로퍼티와 부모 컴포넌트의 상태도 포함된다. -
메모리를 제한하고 부드러운 스크롤을 위해 콘텐츠는 비동기적으로 오프스크린에서 렌더링된다. 이는 스크롤 속도가 채우기 속도보다 빠를 경우 잠깐 빈 화면이 보일 수 있다는 의미다. 이는 각 애플리케이션의 요구에 맞게 조정할 수 있는 트레이드오프이며, 내부적으로 이를 개선하기 위해 노력 중이다.
-
기본적으로 리스트는 각 아이템의
key
프로퍼티를 찾아 React 키로 사용한다. 또는 커스텀keyExtractor
프로퍼티를 제공할 수 있다.
참조
Props
ScrollView Props
ScrollView Props를 상속받는다.
data
getItem
과 getItemCount
에 전달되는 불투명한 데이터 타입으로, 항목을 검색하는 데 사용된다.
타입 |
---|
any |
필수 getItem
(data: any, index: number) => any;
어떤 종류의 데이터 블롭에서 항목을 추출하기 위한 일반적인 접근자이다.
타입 |
---|
function |
필수 getItemCount
(data: any) => number;
데이터 블롭에 포함된 항목의 수를 결정한다.
타입 |
---|
함수 |
필수 renderItem
(info: any) => ?React.Element<any>
data
에서 가져온 항목을 리스트로 렌더링한다.
타입 |
---|
함수 |
CellRendererComponent
CellRendererComponent
는 renderItem
이나 ListItemComponent
로 렌더링된 cell이 기본 ScrollView에 배치될 때, 이를 감싸는 방식을 커스텀하게 정의할 수 있도록 한다. 이 컴포넌트는 cell 내부에서 발생하는 변경 사항을 VirtualizedList에 알리는 이벤트 핸들러를 반드시 받아들여야 한다.
타입 |
---|
React.ComponentType<CellRendererProps> |
ItemSeparatorComponent
각 아이템 사이에 렌더링되지만 맨 위나 맨 아래에는 렌더링되지 않는다. 기본적으로 highlighted
와 leadingItem
프로퍼티가 제공된다. renderItem
은 separators.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
(
data: any,
index: number,
) => {length: number, offset: number, index: number}
타입 |
---|
함수 |
horizontal
true
로 설정하면 아이템을 세로로 쌓는 대신 가로로 나란히 배치한다.
타입 |
---|
boolean |
initialNumToRender
초기에 렌더링할 아이템의 수를 지정한다. 이 값은 화면을 채우기에 충분한 수준으로 설정해야 하지만, 너무 많지 않도록 주의한다. 이 아이템들은 스크롤 상단 이동 시 성능을 향상시키기 위해 윈도우 렌더링 과정에서 절대 언마운트되지 않는다.
타입 | 기본값 |
---|---|
number | 10 |
initialScrollIndex
첫 번째 항목부터 시작하는 대신, initialScrollIndex
에서 시작한다. 이 설정은 첫 번째 initialNumToRender
항목을 항상 렌더링하는 "맨 위로 스크롤" 최적화를 비활성화하고, 초기 인덱스부터 항목을 즉시 렌더링한다. 이 기능을 사용하려면 getItemLayout
을 구현해야 한다.
타입 |
---|
number |
inverted
스크롤 방향을 반전시킨다. -1
스케일 변환을 사용한다.
타입 |
---|
boolean |
keyExtractor
(item: any, index: number) => string;
주어진 아이템과 인덱스에 대해 고유한 키를 추출하는 데 사용한다. 이 키는 캐싱과 아이템 재정렬을 추적하기 위한 React 키로 활용된다. 기본 추출기는 item.key
, item.id
를 차례로 확인하고, 둘 다 없는 경우 React와 마찬가지로 인덱스를 사용한다.
타입 |
---|
함수 |
maxToRenderPerBatch
한 번에 렌더링할 항목의 최대 개수를 지정한다. 한 번에 많은 항목을 렌더링하면 화면 채우기 속도가 빨라지지만, 버튼 터치나 기타 상호작용에 대한 응답성이 떨어질 수 있다. 렌더링 작업이 사용자 입력 처리에 영향을 미칠 수 있기 때문이다.
타입 |
---|
number |
onEndReached
스크롤 위치가 리스트의 논리적 끝에서 onEndReachedThreshold
이내로 접근할 때 한 번 호출된다.
타입 |
---|
(info: {distanceFromEnd: number}) => void |
onEndReachedThreshold
리스트의 끝에서 얼마나 떨어져 있어야 onEndReached
콜백이 트리거되는지를 결정한다. 이 값은 리스트의 보이는 길이 단위로 측정된다. 예를 들어, 0.5로 설정하면 컨텐츠의 끝이 리스트의 보이는 길이의 절반 이내에 있을 때 onEndReached
가 트리거된다.
타입 | 기본값 |
---|---|
number | 2 |
onRefresh
() => void;
이 함수를 제공하면 "당겨서 새로고침(Pull to Refresh)" 기능을 위한 표준 RefreshControl
이 추가된다. 이때 refreshing
속성도 올바르게 설정해야 한다.
타입 |
---|
function |
onScrollToIndexFailed
(info: {
index: number,
highestMeasuredFrameIndex: number,
averageItemLength: number,
}) => void;
아직 측정되지 않은 인덱스로 스크롤을 시도했을 때 실패하는 경우를 처리한다. 일반적으로 직접 오프셋을 계산하여 scrollTo
를 호출하거나, 가능한 한 스크롤한 후 더 많은 아이템이 렌더링된 뒤 다시 시도하는 것을 권장한다.
타입 |
---|
함수 |
onStartReached
리스트의 논리적 시작점에서 onStartReachedThreshold
이내로 스크롤 위치가 들어오면 한 번 호출된다.
타입 |
---|
(info: {distanceFromStart: number}) => void |
onStartReachedThreshold
리스트의 시작 부분에서 콘텐츠의 시작 지점까지 얼마나 떨어져 있어야 onStartReached
콜백이 트리거되는지를 나타낸다. 이 값은 리스트의 보이는 길이 단위로 측정된다. 예를 들어, 값이 0.5라면 콘텐츠의 시작 지점이 리스트의 보이는 길이의 절반 이내에 있을 때 onStartReached
가 트리거된다.
타입 | 기본값 |
---|---|
number | 2 |
onViewableItemsChanged
행의 가시성이 변경될 때 호출된다. 가시성은 viewabilityConfig
속성으로 정의된다.
타입 |
---|
(callback: {changed: ViewToken[], viewableItems: ViewToken[]}) => void |
persistentScrollbar
타입 |
---|
bool |
progressViewOffset
로딩 인디케이터가 올바르게 표시되도록 오프셋이 필요할 때 이 값을 설정한다.
타입 |
---|
number |
refreshControl
커스텀 새로고침 컨트롤 엘리먼트. 이 속성을 설정하면 내장된 기본 <RefreshControl>
컴포넌트를 덮어쓴다. 이 경우 onRefresh
와 refreshing
속성은 무시된다. 이 기능은 수직 방향의 VirtualizedList
에서만 작동한다.
타입 |
---|
엘리먼트 |
새로운 데이터를 갱신(refresh)하는 동안 기다릴 때 이 값을 true
로 설정한다.
타입 |
---|
boolean |
removeClippedSubviews
이 옵션은 큰 목록의 스크롤 성능을 향상시킬 수 있다.
참고: 특정 상황에서 버그(콘텐츠 누락)가 발생할 수 있으므로 주의해서 사용해야 한다.
타입 |
---|
boolean |
renderScrollComponent
(props: object) => element;
커스텀 스크롤 컴포넌트를 렌더링한다. 예를 들어, 스타일이 다른 RefreshControl
을 적용할 수 있다.
타입 |
---|
함수 |
viewabilityConfig
ViewabilityHelper.js
파일에서 플로우 타입과 추가 문서를 확인할 수 있다.
타입 |
---|
ViewabilityConfig |
viewabilityConfigCallbackPairs
ViewabilityConfig
와 onViewableItemsChanged
의 쌍으로 이루어진 리스트다. 특정 ViewabilityConfig
의 조건이 충족되면, 해당하는 onViewableItemsChanged
가 호출된다. 자세한 플로우 타입과 추가 문서는 ViewabilityHelper.js
를 참고한다.
타입 |
---|
ViewabilityConfigCallbackPair 배열 |
updateCellsBatchingPeriod
화면에서 멀리 떨어진 아이템을 렌더링할 때, 낮은 우선순위 렌더링 배치 간의 시간 간격을 설정한다. maxToRenderPerBatch
와 유사하게 렌더링 속도와 반응성 간의 균형을 조절한다.
타입 |
---|
number |
windowSize
화면에 보이는 영역 외부에서 렌더링할 최대 항목 수를 결정한다. 단위는 화면 길이 기준이다. 예를 들어, 리스트가 화면을 가득 채우는 경우, 기본값인 windowSize={21}
은 현재 보이는 화면 영역과 뷰포트 상하로 각각 10개 화면 분량의 항목을 추가로 렌더링한다. 이 값을 줄이면 메모리 사용량이 감소하고 성능이 개선될 수 있지만, 빠르게 스크롤할 때 렌더링되지 않은 빈 공간이 잠시 보일 가능성이 높아진다.
타입 |
---|
number |
메서드
flashScrollIndicators()
flashScrollIndicators();
getScrollableNode()
getScrollableNode(): any;
getScrollRef()
getScrollRef():
| React.ElementRef<typeof ScrollView>
| React.ElementRef<typeof View>
| null;
getScrollResponder()
getScrollResponder () => ScrollResponderMixin | null;
기본 스크롤 응답자에 대한 핸들을 제공한다. this._scrollRef
가 ScrollView
가 아닐 수도 있기 때문에, 해당 메서드를 호출하기 전에 getScrollResponder
에 응답하는지 확인해야 한다.
scrollToEnd()
scrollToEnd(params?: {animated?: boolean});
컨텐츠의 끝으로 스크롤한다. getItemLayout
prop이 없으면 버벅거릴 수 있다.
인자:
이름 | 타입 |
---|---|
params | object |
유효한 params
키는 다음과 같다:
'animated'
(boolean) - 스크롤 시 애니메이션을 적용할지 여부. 기본값은true
이다.
scrollToIndex()
scrollToIndex(params: {
index: number;
animated?: boolean;
viewOffset?: number;
viewPosition?: number;
});
유효한 params
는 다음과 같이 구성된다:
- 'index' (number). 필수.
- 'animated' (boolean). 선택 사항.
- 'viewOffset' (number). 선택 사항.
- 'viewPosition' (number). 선택 사항.
scrollToItem()
scrollToItem(params: {
item: ItemT;
animated?: boolean;
viewOffset?: number;
viewPosition?: number;
);
params
에 유효한 값은 다음과 같다:
- 'item' (Item). 필수.
- 'animated' (boolean). 선택 사항.
- 'viewOffset' (number). 선택 사항.
- 'viewPosition' (number). 선택 사항.
scrollToOffset()
scrollToOffset(params: {
offset: number;
animated?: boolean;
});
리스트에서 특정 콘텐츠 픽셀 오프셋으로 스크롤한다.
offset
파라미터는 스크롤할 오프셋을 지정한다. horizontal
이 true
인 경우, 오프셋은 x값을 의미한다. 그 외의 경우에는 오프셋이 y값을 나타낸다.
animated
파라미터(기본값은 true
)는 스크롤 시 애니메이션을 사용할지 여부를 결정한다.