Skip to main content

기본적이고 단순한 리스트를 렌더링하기 위한 고성능 인터페이스로, 가장 유용한 기능들을 제공한다:

  • 완전한 크로스 플랫폼 지원
  • 선택적 수평 모드
  • 구성 가능한 가시성 콜백
  • 헤더 지원
  • 푸터 지원
  • 구분선 지원
  • 당겨서 새로고침
  • 스크롤 로딩
  • ScrollToIndex 지원
  • 다중 컬럼 지원

섹션 지원이 필요하다면 <SectionList>를 사용한다.

여러 컬럼을 렌더링하려면 numColumns prop을 사용한다. flexWrap 레이아웃 대신 이 방식을 사용하면 아이템 높이 로직과의 충돌을 방지할 수 있다.

아래는 더 복잡한 선택 가능한 예제이다.

  • extraData={selectedId}FlatList에 전달하면 상태가 변경될 때 FlatList가 리렌더링되도록 보장한다. 이 prop을 설정하지 않으면 FlatListPureComponent이기 때문에 prop 비교 시 변경 사항이 없어 리렌더링이 필요하다는 것을 알지 못한다.
  • keyExtractor는 리스트가 기본 key 속성 대신 id를 React 키로 사용하도록 지시한다.

이것은 <VirtualizedList>를 편리하게 래핑한 것이므로, 여기에 명시적으로 나열되지 않은 props(또는 <ScrollView>의 props)를 상속받는다. 단, 다음과 같은 주의사항이 있다:

  • 내용이 렌더링 윈도우를 벗어나면 내부 상태가 유지되지 않는다. 모든 데이터가 아이템 데이터 또는 Flux, Redux, Relay와 같은 외부 저장소에 캡처되었는지 확인한다.
  • 이 컴포넌트는 PureComponent이므로 props가 얕은 비교에서 동일하면 리렌더링되지 않는다. renderItem 함수가 의존하는 모든 것이 업데이트 후 ===이 아닌 prop(예: extraData)으로 전달되었는지 확인한다. 그렇지 않으면 UI가 변경되지 않을 수 있다. 여기에는 data prop과 부모 컴포넌트 상태가 포함된다.
  • 메모리를 제한하고 부드러운 스크롤을 가능하게 하기 위해 내용은 비동기적으로 오프스크린에서 렌더링된다. 이는 채우기 속도보다 빠르게 스크롤할 수 있고 잠시 빈 내용을 볼 수 있음을 의미한다. 이는 각 애플리케이션의 필요에 맞게 조정할 수 있는 트레이드오프이며, 우리는 이를 개선하기 위해 노력하고 있다.
  • 기본적으로 리스트는 각 아이템의 key prop을 찾아 React 키로 사용한다. 또는 커스텀 keyExtractor prop을 제공할 수 있다.

참조

Props

VirtualizedList Props

VirtualizedList Props를 상속받는다.


필수
renderItem

tsx
renderItem({
item: ItemT,
index: number,
separators: {
highlight: () => void;
unhighlight: () => void;
updateProps: (select: 'leading' | 'trailing', newProps: any) => void;
}
}): JSX.Element;

data에서 아이템을 가져와 리스트에 렌더링한다.

필요한 경우 index와 같은 추가 메타데이터를 제공한다. 또한 highlightunhighlight(이들은 highlighted: boolean prop을 설정)가 사용 사례에 충분하지 않을 때, 선행 또는 후행 구분자(separator)의 렌더링을 변경하기 위해 어떤 prop이든 설정할 수 있는 separators.updateProps 함수도 제공한다.

타입
function
  • item (Object): 렌더링될 data의 아이템
  • index (number): data 배열에서 이 아이템에 해당하는 인덱스
  • separators (Object)
    • highlight (Function)
    • unhighlight (Function)
    • updateProps (Function)
      • select (enum('leading', 'trailing'))
      • newProps (Object)

사용 예시:

tsx
<FlatList
ItemSeparatorComponent={
Platform.OS !== 'android' &&
(({highlighted}) => (
<View
style={[style.separator, highlighted && {marginLeft: 0}]}
/>
))
}
data={[{title: 'Title Text', key: 'item1'}]}
renderItem={({item, index, separators}) => (
<TouchableHighlight
key={item.key}
onPress={() => this._onPress(item)}
onShowUnderlay={separators.highlight}
onHideUnderlay={separators.unhighlight}>
<View style={{backgroundColor: 'white'}}>
<Text>{item.title}</Text>
</View>
</TouchableHighlight>
)}
/>

필수
data

렌더링할 항목들의 배열(또는 배열과 유사한 리스트). 다른 데이터 타입을 사용하려면 VirtualizedList를 직접 타겟팅해야 한다.

타입
ArrayLike

ItemSeparatorComponent

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

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

ListEmptyComponent

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

타입
컴포넌트, 엘리먼트

ListFooterComponent

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

타입
component, element

ListFooterComponentStyle

ListFooterComponent 내부 View를 위한 스타일링 정보를 담고 있다.

타입
View 스타일

ListHeaderComponent

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

타입
컴포넌트, 엘리먼트

ListHeaderComponentStyle

ListHeaderComponent 내부 View를 위한 스타일링을 정의한다.

타입
View 스타일

columnWrapperStyle

numColumns > 1인 경우, 여러 아이템으로 구성된 행에 적용할 수 있는 커스텀 스타일이다. 이 속성은 선택적으로 사용할 수 있다.

타입
View Style

extraData

리스트를 리렌더링하도록 지시하는 마커 속성이다. (PureComponent를 구현하기 때문) 만약 renderItem, Header, Footer 등의 함수가 data prop 외부의 어떤 것에 의존한다면, 이곳에 추가하고 불변하게 처리한다.

타입
any

getItemLayout

tsx
(data, index) => {length: number, offset: number, index: number}

getItemLayout은 동적 콘텐츠의 크기를 미리 알고 있을 때, 측정 과정을 건너뛸 수 있게 해주는 선택적 최적화 기능이다. 아이템의 크기가 고정되어 있는 경우, getItemLayout을 사용하면 효율적이다. 예를 들어:

tsx
  getItemLayout={(data, index) => (
{length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
)}

getItemLayout을 추가하면 수백 개의 아이템을 가진 리스트에서 성능을 크게 향상시킬 수 있다. ItemSeparatorComponent를 지정한 경우, 오프셋 계산에 구분자의 길이(높이 또는 너비)를 포함해야 한다.

타입
함수

horizontal

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

타입
boolean

initialNumToRender

화면에 처음 렌더링할 아이템의 수를 설정한다. 이 값은 화면을 채우기에 충분해야 하지만 너무 많지 않아야 한다. 이 아이템들은 스크롤을 맨 위로 올리는 동작의 성능을 높이기 위해 윈도우 렌더링 과정에서 절대 언마운트되지 않는다.

타입기본값
number10

initialScrollIndex

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

타입
number

inverted

스크롤 방향을 반대로 설정한다. -1 스케일 변환을 사용하여 구현한다.

타입
boolean

keyExtractor

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

특정 인덱스에 위치한 아이템의 고유 키를 추출하는 데 사용한다. 이 키는 캐싱과 아이템 재정렬을 추적하기 위한 React 키로 활용된다. 기본 추출기는 item.key, item.id를 차례로 확인한 후, React와 마찬가지로 인덱스를 사용한다.

타입
함수

numColumns

numColumns는 여러 개의 컬럼을 렌더링할 때 사용한다. 단, 이 기능은 horizontal={false}로 설정한 경우에만 동작하며, flexWrap 레이아웃처럼 지그재그 형태로 아이템을 배치한다. 모든 아이템의 높이가 동일해야 하며, masonry 레이아웃은 지원하지 않는다.

타입
number

onRefresh

tsx
() => void;

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

타입
function

onViewableItemsChanged

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

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

progressViewOffset

로딩 인디케이터가 정확하게 표시되기 위해 오프셋이 필요할 때 이 값을 설정한다.

타입
number

refreshing

새로운 데이터를 갱신하는 동안 이 값을 true로 설정한다.

타입
boolean

removeClippedSubviews

이 옵션은 긴 목록의 스크롤 성능을 향상시킬 수 있다. 안드로이드에서는 기본값이 true로 설정되어 있다.

주의: 특정 상황에서 버그(콘텐츠 누락)가 발생할 수 있으므로 사용에 주의가 필요하다.

타입
boolean

viewabilityConfig

자세한 Flow 타입과 문서는 ViewabilityHelper.js에서 확인할 수 있다.

타입
ViewabilityConfig

viewabilityConfigViewabilityConfig 타입의 객체를 받는다. 이 객체는 다음과 같은 속성을 가진다.

속성타입
minimumViewTimenumber
viewAreaCoveragePercentThresholdnumber
itemVisiblePercentThresholdnumber
waitForInteractionboolean

viewAreaCoveragePercentThreshold 또는 itemVisiblePercentThreshold 중 적어도 하나는 반드시 필요하다. 이 설정은 constructor에서 해야 하며, 그렇지 않으면 다음과 같은 오류가 발생할 수 있다(참고):

  Error: Changing viewabilityConfig on the fly is not supported
tsx
constructor (props) {
super(props)

this.viewabilityConfig = {
waitForInteraction: true,
viewAreaCoveragePercentThreshold: 95
}
}
tsx
<FlatList
viewabilityConfig={this.viewabilityConfig}
...

minimumViewTime

아이템이 실제로 보여지는 최소 시간(밀리초 단위)을 지정한다. 이 시간 동안 아이템이 화면에 노출되어야 뷰어빌리티 콜백이 실행된다. 이 값을 높게 설정하면, 스크롤을 멈추지 않고 빠르게 지나갈 경우 해당 콘텐츠를 보여지는 것으로 간주하지 않는다.

viewAreaCoveragePercentThreshold

뷰포트에서 부분적으로 가려진 아이템이 '보여지는' 것으로 간주되려면, 뷰포트의 몇 퍼센트가 해당 아이템으로 덮여 있어야 하는지를 나타내는 값이다. 범위는 0에서 100 사이이며, 완전히 보이는 아이템은 항상 '보여지는' 것으로 간주된다. 값이 0이면 뷰포트에 단 하나의 픽셀만 보여도 아이템이 보여지는 것으로 간주되고, 값이 100이면 아이템이 완전히 보이거나 뷰포트 전체를 덮어야만 보여지는 것으로 간주된다.

itemVisiblePercentThreshold

viewAreaCoveragePercentThreshold와 유사하지만, 뷰어블 영역을 얼마나 차지하는지가 아니라 아이템 자체가 얼마나 보이는지를 고려한다.

사용자가 스크롤하거나 렌더링 후 recordInteraction을 호출하기 전까지는 어떤 것도 화면에 보이는 상태로 간주하지 않는다.

viewabilityConfigCallbackPairs

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

타입
ViewabilityConfigCallbackPair의 배열

메서드

flashScrollIndicators()

tsx
flashScrollIndicators();

스크롤 인디케이터를 잠시 동안 표시한다.

getNativeScrollRef()

tsx
getNativeScrollRef(): React.ElementRef<typeof ScrollViewComponent>;

기본 스크롤 컴포넌트에 대한 참조를 제공한다.

getScrollResponder()

tsx
getScrollResponder(): ScrollResponderMixin;

기본 스크롤 응답자에 대한 핸들을 제공한다.

getScrollableNode()

tsx
getScrollableNode(): any;

기본 스크롤 노드에 대한 핸들을 제공한다.

scrollToEnd()

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

컨텐츠의 끝까지 스크롤한다. getItemLayout 속성이 없으면 부드럽지 않을 수 있다.

인자:

이름타입
paramsobject

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

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

scrollToIndex()

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

지정한 인덱스에 해당하는 아이템을 화면 내에서 스크롤하여 위치시킨다. viewPosition 값이 0이면 아이템을 상단에, 1이면 하단에, 0.5면 중앙에 위치시킨다.

참고: getItemLayout 속성을 지정하지 않으면 렌더링된 윈도우 바깥의 위치로는 스크롤할 수 없다.

매개변수:

이름타입
params
필수
object

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

  • 'animated' (boolean) - 스크롤 시 애니메이션을 적용할지 여부. 기본값은 true.
  • 'index' (number) - 스크롤할 대상 인덱스. 필수.
  • 'viewOffset' (number) - 최종 목표 위치에서 고정할 픽셀 단위 오프셋.
  • 'viewPosition' (number) - 0이면 인덱스로 지정된 아이템을 상단에, 1이면 하단에, 0.5면 중앙에 위치시킨다.

scrollToItem()

tsx
scrollToItem(params: {
animated?: ?boolean,
item: Item,
viewPosition?: number,
});

데이터를 선형으로 스캔해야 하므로 가능하면 scrollToIndex를 사용하는 것이 좋다.

참고: getItemLayout 속성을 지정하지 않으면 렌더링 윈도우 외부의 위치로 스크롤할 수 없다.

매개변수:

이름타입
params
필수
object

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

  • 'animated' (boolean) - 스크롤 시 애니메이션을 적용할지 여부. 기본값은 true.
  • 'item' (object) - 스크롤할 대상 아이템. 필수.
  • 'viewPosition' (number)

scrollToOffset()

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

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

매개변수:

이름타입
params
필수
object

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

  • 'offset' (number) - 스크롤할 오프셋. horizontal이 true인 경우, 오프셋은 x값을 의미하고, 그 외의 경우에는 y값을 의미한다. 필수.
  • 'animated' (boolean) - 스크롤 시 애니메이션을 사용할지 여부. 기본값은 true이다.