React Native) 캐러셀 만들기 (feat. FlatList)

2ast·2022년 10월 6일
0
post-custom-banner

이전에 ScrollView를 이용해 캐러셀 만드는 방법에 대해서 올린 적이 있는데, FlatList를 이용해도 동일한 캐러셀을 만들 수 있다. 이번에는 FlatList를 이용해 캐러셀 만들기를 해볼 예정이다.

일단 결과물 부터 보고 시작

//ScrollViewCarousel.tsx
import styled from '@emotion/native';
import React, {useState} from 'react';
import {FlatList} from 'react-native';

const CarouselContainer = styled.View`
  flex: 1;
`;
const CarouselItemContainer = styled.View`
  width: ${(props: {width: number}) => props.width}px;
  height: 100%;
  padding: 20px;
`;
const CarouselItem = styled.View`
  flex: 1;
  background-color: ${(props: {color: string}) => props.color};
`;

const FlatListCarousel = () => {
  const data = ['tomato', 'skyblue', 'green', 'beige', 'yellow'];
  const [itemWidth, setItemWidth] = useState(0);

  const renderItem = ({item}: {item: string}) => {
    return (
      <CarouselItemContainer key={item} width={itemWidth}>
        <CarouselItem color={item} />
      </CarouselItemContainer>
    );
  };

  return (
    <CarouselContainer>
      <FlatList
        data={data}
        keyExtractor={item => item}
        renderItem={renderItem}
        horizontal
        contentContainerStyle={{width: `${100 * data.length}%`}}
        pagingEnabled
        showsHorizontalScrollIndicator={false}
        onContentSizeChange={w => setItemWidth(w / data.length)}
      />
    </CarouselContainer>
  );
};

export default FlatListCarousel;

---------------------------------------
//App.tsx
import React from 'react';
import styled from '@emotion/native';
import FlatListCarousel from './src/components/FlatListCarousel';

const AppBackground = styled.View`
  justify-content: center;
  align-items: center;
  flex: 1;
  background-color: black;
`;

const CarouselBox = styled.View`
  width: 80%;
  height: 60%;
  border-radius: 10px;
  background-color: white;
  overflow: hidden;
`;

const App = () => {
  return (
    <AppBackground>
      <CarouselBox>
        <FlatListCarousel />
      </CarouselBox>
    </AppBackground>
  );
};

export default App;

설명하자면 이렇습니다.

 <FlatList
        data={data}
        keyExtractor={item => item}
        renderItem={renderItem}
        horizontal
        contentContainerStyle={{width: `${100 * data.length}%`}}
        pagingEnabled
        showsHorizontalScrollIndicator={false}
        onContentSizeChange={w => setItemWidth(w / data.length)}
      />

이번에도 캐러셀의 설정은 모두 FlatList 컴포넌트의 속성에서 이루어지며, 그 원리도 ScrollView와 동일하다. contentContainerStyle 속성을 통해 contentContainer의 width를 CarouselContainer의 width에 data의 길이를 곱한 만큼 주었다. 그리고 onContentSizeChange를 사용해 퍼센트로 계산된 contentContainer의 width를 정확한 px값으로 가져왔다. 이제 이렇게 받아온 width 값을 다시 캐러셀에 보여주고 싶은 data의 갯수만큼 나눠서 각 아이템의 width가 CarouselContainer에 가득 차도록 width 값을 얻어내면 가장 어려운 작업은 끝났다.

ScrollView로 구현하는 캐러셀과 비교해 다른 점이라고는 data, keyExtractor, renderItem 속성을 이용해 render를 하느냐, View 내부에 map을 사용해 직접 render하느냐의 차이일 뿐이다.

profile
React-Native 개발블로그
post-custom-banner

0개의 댓글