[React Native] ScrollView와 FlatList

React Native에서 스크롤 가능한 영역을 만들 때 사용하는 두 컴포넌트를 정리해보자!

 

 

ScrollView

ScrollView는 모든 자식 요소를 한번에 로드하고 렌더링하는 스크롤 컨테이너다.

따라서 스크롤 가능한 컨텐츠가 적거나, 컨텐츠가 한정되어 있을 때 사용하는 것이 좋다.

 

웹개발시 JSX로 목록을 렌더링할 때 많이 사용했듯이 map 등을 이용해 스크롤할 요소들을 ScrollView의 자식컴포넌트로 지정해준다.

 

예시

<View style={styles.goalsContainer}>
  <ScrollView>
    {courseGoals.map((goal) => (
      <View style={styles.goalItem}>
        <Text key={goal} style={styles.goalText}>
          {goal}
        </Text>
      </View>
    ))}
  </ScrollView>
</View>

courseGoals라는 배열에 담긴 goal들을 Text 컴포넌트로 출력하는 예시다.

 

ScrollView는 기본적으로 내부(자식) 요소의 크기에따라 크기가 조절되고, flex를 무시하므로 flex를 이용해 화면 구성 비율을 지정하고 싶은 경우 View로 한번 감싸 그 View에 flex를 지정해주는 방법을 활용한다.

 

FlatList

FlatList는 ScrollView와 다르게 필요할 때만 스크롤될 요소들을 렌더링한다.

따라서 스크롤 아이템이 동적으로 추가될 가능성이 있거나, 대량일 때 사용하면 좋다.

ex. 채팅창, 뉴스피드(무한스크롤)

 

예시

const [courseGoals, setCourseGoals] = useState([]);
const addGoalHandler = () => {
    setCourseGoals((currentCourseGoals) => [
      ...currentCourseGoals,
      { text: enteredGoalText, key: Math.random().toString() },
    ]);
  };
  
  // 생략
  
  return (
        <FlatList
        data={courseGoals}
        renderItem={(itemData) => {
          return (
            <View style={styles.goalItem}>
              <Text style={styles.goalText}>{itemData.item.text}</Text>
            </View>
          );
        }}
        style={styles.goalsContainer}
      />
  );

위 예시를 FlatList로 변경한 예시다.

여는 태그와 닫는 태그 사이에 스크롤될 요소(아이템)들을 추가해주던 방식과는 조금 다르다!

 

특정한 목록을 FlatList를 이용해 스크롤 아이템들로 지정해주기 위해선 아래 프로퍼티들을 설정해주자

  • data: 렌더링할 아이템이 담긴 배열
  • renderItem: 각 아이템을 렌더링할 함수로, 아이템을 인자로 받는다.

JSX에서 반복문으로 어떤 요소를 렌더링하려면 고유한 key를 설정해줘야하는데 FlatList의 renderItem에는 key가 없어도 아무런 경고가 발생하지 않는다.

이유는 현재 각 renderItem에는 key가 포함돼있기 때문이다.

[{ text: '목표1', key: Math.random().toString() }, ... ]  // 이런 형태!

 

FlatList는 위와같이 renderItem에서 key를 찾아서 반영할 수 있다.

 

하지만 지금처럼 직접 목록을 만든 경우가 아닌, API 등에서 받아온 데이터에 key가 없는데 가공없이 사용해야할 때는 어떻게해야할까?

 

예시2 - key 프로퍼티가 없는 데이터 출력하기

const [courseGoals, setCourseGoals] = useState([]);
const addGoalHandler = () => {
    setCourseGoals((currentCourseGoals) => [
      ...currentCourseGoals,
      { text: enteredGoalText, id: Math.random().toString() },
    ]);
  };
  
  // 생략
  
  return (
        <FlatList
        data={courseGoals}
        renderItem={(itemData) => {
          return (
            <View style={styles.goalItem}>
              <Text style={styles.goalText}>{itemData.item.text}</Text>
            </View>
          );
        }}
        style={styles.goalsContainer}
        keyExtractor={(item) => item.id}
      />
  );

이럴 때는 FlatList의 keyExtractor 프로퍼티를 사용한다.

  • keyExtractor: 각 아이템의 고유한 key를 반환하는 함수

 

FlatList의 주요 프로퍼티

  • data: 렌더링할 아이템 배열
  • renderItem: 각 아이템을 렌더링하는 함수
  • keyExtractor: 각 아이템의 고유한 key를 반환하는 함수
  • onEndReached: 목록의 끝에 도달했을 때 실행되는 콜백함수
  • onRefresh: 새로고침시 실행되는 함수