[ React Native ] FlatList + slide card
grid layout을 할려고 style을 적용해보는데 react native에는 flex: grid가 없어서 찾아보다가
그리드 기능을 해주는 flatList를 이용
Useage
flatList는 가로 세로 두가지를 할 수 있으며 각각 사용법이 다르다.
1. vertical
우선 flaticon에서 해당 월의 개수만큼 박스를 만들려고해서
해당 월의 마지막날을 data로 넣어주었다.
numColums는 한 줄에 몇개를 할지 설정할 수 있다.
이후 박스 영역 안에 넣어줘야하므로 onLayout을 이용해 박스 영역의 크기를 계산하여 박스 영역 안에 들어가는 item 박스의 크기를 계산
columWrapperStyle로 각 아이템의 간격을 설정
이후 renderItem으로 아이템 박스를 생성
const GAP = 4;
const numColumns = 10;
const itemWidth = boxWidth
? Math.floor((boxWidth - GAP * (numColumns - 1) - 25) / numColumns)
: 0;
<BoxView
onLayout={(e) => {
const { width } = e.nativeEvent.layout;
setBoxWidth(width);
}}>
<BetweenView style={styles.btwSpace}>
<AppText>{prop.title}</AppText>
<SvgIcon name='Dot' fill/>
</BetweenView>
<View style={styles.metricContainer}>
<FlatList
data={Array.from({ length: daysInMonth }, (_, i) => i)}
keyExtractor={(item) => item.toString()}
numColumns={numColumns}
columnWrapperStyle={{ gap: GAP }}
renderItem={() =>
<View style={[styles.metric, {
width: itemWidth,
height: itemWidth,
}]} />
}
/>
</View>
</BoxView>
그럼 한줄에 10개인 아이템 박스가 4줄로 나오게 된다.
여기서 style로 flex: row 를 활용하지 않고 flatList를 사용한 이유는 flex:row를 사용하다보면 양끝의 빈 공간이 문제가 생겨서 flatList를 활용했다.

1. horizontal
그럼 이제 위에 만든 박스를 여러개 만들어서 slide를 적용해서 움직일 수 있게 구현
slide도 flatList를 활용하면 쉽게 구현할 수 있다.
사용방법은 vertical과 비슷하다
horizontal속성을 넣어주고
showsHorizontalScrollIndicator={false}
- UI를 깔끔하게 보이게 할 때 사용
- 가로 스크롤을 숨겨준다.
decelerationRate="fast"
- 스크롤 감속 속도를 제어
- "normal" : 기본 속도
- "fast" : 손을 놓았을 때 더 빨리 멈춤 → 스냅 느낌 강화
snapToInterval={ITEM_WIDTH + ITEM_SPACING}
- 스냅 단위 거리 지정
- FlatList가 스크롤 끝에 멈출 때 얼마만큼 이동할지 결정
- 여기서는 “카드 하나 + 오른쪽 간격” 만큼 스크롤 → 한 번에 한 카드 단위로 멈춤
snapToAlignment="start"
- 스냅 위치를 시작점(왼쪽) 기준으로 맞춤
- "center" : 스냅 위치를 카드 중앙 기준
- "end" : 카드 오른쪽 기준
const metrics = [
{ id: 1, component: <MetricItem title="metric 1"/>},
{ id: 2, component: <MetricItem title="metric 2"/>},
{ id: 3, component: <MetricItem title="metric 3"/>},
]
return (
<View>
<BetweenView style={styles.btwSpace}>
<AppText>( {metrics.length} )</AppText>
<SvgIcon name='Dot' fill/>
</BetweenView>
<FlatList
data={metrics}
horizontal
showsHorizontalScrollIndicator={false}
decelerationRate="fast"
snapToInterval={ITEM_WIDTH + ITEM_SPACING}
snapToAlignment="start"
keyExtractor={item => item.id.toString()}
renderItem={({item,index}) => (
<View style={{width: ITEM_WIDTH,
marginRight: index === metrics.length - 1 ? 0 : ITEM_SPACING, }}>
{item.component}
</View>
)}
/>
</View>
)
그럼 스크롤하면 자연스럽게 스크롤이 되는것을 확인할 수 있다.

