Just Do IT!

[React Native] ScrollView 대신 FlatList 사용하기 본문

개발 공부/React Native

[React Native] ScrollView 대신 FlatList 사용하기

MOON달 2023. 1. 4. 16:06
728x90
ScrollView와 FlatList의 차이
  • ScrollView
    • 모든 리스트들을 한번에 렌더링해야 하기 때문에 리스트가 많을수록 성능이 저하된다
    • 출력해야 하는 데이터가 고정적이고 많지 않을 때 간단하게 사용할 수 있는 컴포넌트
  • FlatList
    • 화면에 보이지 않는 리스트들은 메모리에서 제거하고 화면에 보이는 부분들만 렌더링
    • 리스트가 많이 있어도 성능 저하를 최소화
    • 무한스크롤 적용에 적합하다
    • JS에서의 map 함수 역할과 비슷하나 더 많은 기능을 내포하고 있어 react-native에서 많이 쓰이는 컴포넌트
    • 데이터의 길이가 가변적이고, 데이터의 양을 예측할 수 없는 경우 (API를 통해 외부에서 크기를 알 수 없는 데이터를 가져오는 경우)에 사용하기 적절

 

 

 

 

FlatList로 리팩토링하기

top rated movies (movie review 앱 중 scrollview로 만들었던 코드 리팩토링하기)

...

{/* Top Rated movies */}
          <ListTitle>Top Rated Movies</ListTitle>
          <FlatList
            horizontal
            contentContainerStyle={{ paddingHorizontal: 20 }}
            showsHorizontalScrollIndicator={false}
            data={topRated}
            renderItem={({ item }) => <TopRated movie={item} />}
            keyExtractor={(item) => item.id}
            ItemSeparatorComponent={<View style={{ width: 10 }} />}
          />
          
...

 

FlatList는 <FlatList></FlatList> 형식으로 쓸 수 없다. (이 점 반드시 주의하기!)

map 역시 사용하지 않아도 props에 존재하기 때문에 훨씬 코드가 깔끔해진다.

 

 

 

 

FlatList의 prop 중 많이 쓰이는 props
  • data : 만들고자 하는 리스트의 soucre를 담는 prop
  • renderItem : data로 받은 소스들 그 각각의 item들을 render시켜주는 콜백함수 (반드시 item으로 작성해야 함)
  • keyExtractor : map함수에서 key={idex} 와 해줬듯이 각각의 item에 고유의 키를 주는 것이라 생각하면 된다
  • ItemSeparatorComponent : 원래는 margin으로 각 리스트 사이의 magin을 줬는데 그럴 필요 없이 이 prop를 사용하면 편하게 margin을 줄 수가 있다
  • ListHeaderComponent : FlatList로 정렬하는 리스트를 제외하고 상단에 별도의 컴포넌트를 배치할 수 있다
  • ListFooterComponent : Footer에 배치 (위와 역할은 같음)

 

예시) Movies.js

<FlatList
      refreshing={isRefreshing}
      onRefresh={onRefresh}
      ListHeaderComponent={
        <>
          {/* Main : movie poster & title/content (background: movie image)  */}
          <Swiper height="100%" showsPagination={false} autoplay loop>
            {nowPlayings.map((movie) => (
              <Slide key={movie.id} movie={movie} />
            ))}
          </Swiper>

          {/* Top Rated movies */}
          <ListTitle>Top Rated Movies</ListTitle>
          <FlatList
            horizontal
            contentContainerStyle={{ paddingHorizontal: 20 }}
            showsHorizontalScrollIndicator={false}
            data={topRated}
            renderItem={({ item }) => <TopRated movie={item} />}
            keyExtractor={(item) => item.id}
            ItemSeparatorComponent={<View style={{ width: 10 }} />}
          />

          {/* UpComing movies */}
          <ListTitle>Upcoming Movies</ListTitle>
        </>
      }
      data={upComing}
      renderItem={({ item }) => <UpComing movie={item} />}
      keyExtractor={(item) => item.id}
      ItemSeparatorComponent={<View style={{ height: 15 }} />}
    />

Main과 Top Rated Movies는 ListHeaderComponent를 이용해 상단에 별도의 컴포넌트로 표현하고,

Upcoming Movies는 FlatList를 이용해서 리스트를 받으면 코드가 훨씬 간결해진다.

 

여전히 동일하게 작동중인 화면

 

 

 


지금은 좀 복잡해 보이지만, 익숙해지면 필요할 때 적절하게 잘 사용할 수 있을 것 같다.

prop만 좀 더 열심히 공부해둬야겠다.

 

공식문서: https://reactnative.dev/docs/flatlist

 

FlatList · React Native

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

reactnative.dev