Skip to main content
Version: Next

FlatList

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

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

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

예제​

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

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

  • extraData={selectedId}를 FlatList에 전달해 상태가 변경될 때 FlatList가 리렌더링되도록 한다. 이 속성을 설정하지 않으면 FlatList는 PureComponent이기 때문에 속성 비교에서 변경 사항을 감지하지 못해 아이템을 리렌더링하지 않는다.
  • keyExtractor는 리스트가 기본 key 속성 대신 id를 React 키로 사용하도록 지시한다.

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

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

참고 자료

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와 같은 추가 메타데이터를 제공하며, 더 일반적인 separators.updateProps 함수를 통해 리딩 또는 트레일링 구분자의 렌더링을 변경할 수 있다. highlight와 unhighlight (이들은 highlighted: boolean prop을 설정한다)가 충분하지 않은 경우에 유용하다.

타입
함수
  • item (객체): 렌더링될 data의 아이템.
  • index (숫자): data 배열에서 이 아이템에 해당하는 인덱스.
  • separators (객체)
    • highlight (함수)
    • unhighlight (함수)
    • updateProps (함수)
      • select (enum('leading', 'trailing'))
      • newProps (객체)

사용 예시:

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​

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

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

ListEmptyComponent​

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

타입
컴포넌트, 엘리먼트

ListFooterComponent​

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

타입
컴포넌트, 엘리먼트

ListFooterComponentStyle​

ListFooterComponent 내부 View에 적용할 스타일을 정의한다.

타입
View 스타일

ListHeaderComponent​

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

타입
component, element

ListHeaderComponentStyle​

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

타입
View 스타일

columnWrapperStyle​

numColumns > 1일 때 생성되는 다중 아이템 행에 적용할 수 있는 커스텀 스타일을 지정한다.

타입
View Style

extraData​

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

타입
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를 지정한 경우, 오프셋 계산에 구분자의 길이(높이 또는 너비)를 포함해야 한다.

타입
function

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 prop도 올바르게 설정해야 한다.

타입
function

onViewableItemsChanged​

행의 가시성이 변경될 때 호출되는 콜백 함수. 이 동작은 viewabilityConfig prop에 정의된 기준에 따라 결정된다.

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

progressViewOffset​

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

타입
number

refreshing​

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

타입
boolean

removeClippedSubviews​

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

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

타입
boolean

viewabilityConfig​

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

타입
ViewabilityConfig

viewabilityConfig는 ViewabilityConfig 타입을 받는다. 이 타입은 다음과 같은 속성을 가진 객체이다.

속성타입
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​

minimumViewTime은 viewability 콜백이 실행되기 전에 아이템이 실제로 보여야 하는 최소 시간(밀리초 단위)을 의미한다. 이 값을 크게 설정하면, 스크롤을 멈추지 않고 빠르게 지나가는 콘텐츠는 '보이는 상태'로 간주되지 않는다.

viewAreaCoveragePercentThreshold​

뷰포트에서 부분적으로 가려진 아이템이 "보이는 상태"로 간주되기 위해 차지해야 하는 비율을 나타낸다. 범위는 0부터 100까지다. 완전히 보이는 아이템은 항상 보이는 상태로 간주된다. 값이 0이면 뷰포트에 단 하나의 픽셀만 보여도 아이템이 보이는 상태로 판단된다. 반면 값이 100이면 아이템이 완전히 보이거나 전체 뷰포트를 차지해야 보이는 상태로 간주된다.

itemVisiblePercentThreshold​

viewAreaCoveragePercentThreshold와 유사하지만, 뷰 영역에서 차지하는 비율 대신 아이템이 얼마나 보이는지를 기준으로 한다.

waitForInteraction​

사용자가 스크롤하거나 렌더링 후 recordInteraction이 호출되기 전까지는 아무것도 보이는 상태로 간주되지 않는다.

viewabilityConfigCallbackPairs​

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

타입
ViewabilityConfigCallbackPair 배열

메서드​

flashScrollIndicators()​

tsx
flashScrollIndicators();

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

getNativeScrollRef()​

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

스크롤 컴포넌트의 실제 참조를 제공한다.

getScrollResponder()​

tsx
getScrollResponder(): ScrollResponderMixin;

기본 스크롤 응답자(responder)에 대한 핸들러를 제공한다.

getScrollableNode()​

tsx
getScrollableNode(): any;

스크롤 가능한 노드에 대한 핸들을 제공한다.

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;
});

지정된 인덱스에 위치한 아이템을 뷰포트 내에서 스크롤하여 보여준다. 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 prop을 지정하지 않으면 렌더링 윈도우 외부의 위치로 스크롤할 수 없다.

매개변수:

이름타입
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.