이번 프로젝트에서 react-native-snap-carousel 을 이용해서 지도의 마커들의 정보를 렌더하고 있었다. 링크를 확인해보면 아이템들의 정보를 하나의 카드안에 렌더하고 그 카드를 옆으로 스와이프하면 다음 인덱스의 아이템을 렌더하는 방식이다. 기본적으로 react-native 의 FlatList
컴포넌트를 기반으로 개발했다고 한다.
이 react-native-snap-carousel
을 사용해서 아래와 같은 기능들을 구현하고자 하였다.
하지만 여러가지 문제가 발생했었는데,
첫번째는 정보창에 일치하지 않는 마커의 정보를 렌더하는 경우가 발생하는 점이었다.
두번째는 스와이프 했을 때 일치하지 않는 마커의 정보를 렌더하는 점이었다.
이 두 가지 문제들이 발생하는 원초적인 이유는 마커들의 배열을 관리하는 방식과 react-native-snap-carousel
에서 인덱스로 아이템 정렬 기준을 정한다는 점이었다.
react-native-snap-carousel 의 예제 코드를 참조하자면,
import Carousel from 'react-native-snap-carousel';
export class MyCarousel extends Component {
_renderItem = ({item, index}) => {
return (
<View style={styles.slide}>
<Text style={styles.title}>{ item.title }</Text>
</View>
;
}
render () {
return (
<Carousel
ref={(c) => { this._carousel = c; }}
data={this.state.entries}
renderItem={this._renderItem}
sliderWidth={sliderWidth}
itemWidth={itemWidth}
/>
);
}
}
여기서 data
렌더시킬 배열을 받고, _renderItem
의 인자로 들어가는 item, index
는 data
에서 받아온 값들이 된다. 마커를 클릭해서 해당 정보를 정보창에 렌더할 때, 해당 carousel 을 해당 아이템으로 맞춰주는 메서드인 onSnapToItem
에서도 인자를 index
로 받게 된다.
그래서 해결하려고 노력한 방식들은,
요청을 보내 마커를 받아올 때, 또 다른 배열 carousels
에도 같은 응답의 값(마커 배열)들을 할당해주었다.
여기서 인덱스가 아닌, 아이템들이 지닌 고유한 값을 보면 catId
가 있었다. 이 catId
를 이용해서 해당 아이템이 몇 번째 인덱스에 위치하는지 알아낼 수 있었다.
하지만 여기서 두 번째 방식을 실행할 때의 문제점인데, 알아낸 해당 인덱스가 화면에 따라 받아오는 개수가 달라지는 마커의 배열보다 클 수도 있다는 점이다.
react-native-snap-carousel
의 이런 render 시스템이 이번 지도의 마커를 이용한 기능에 걸림돌이 되었다. 현재 지도에서 화면 범위(bound)를 요청으로 보내면 서버에서 그 범위안에 존재하는 마커를 필터하여 응답으로 보내준다. 해당 배열은 id
순으로 정렬되어 있는데, 이 순서는 마커를 클릭한 순간, carousel
에서 렌더하는 요소들이 달라지면서 마커 배열과는 다른 고유의 인덱스를 가지게 된다. 결국 해결하기 위해서는 모든 마커를 데이터로 받아 carousel
과 연동하여 변하지 않는 인덱스를 이용하는 방법과 carousel
에서 해당 데이터의 인덱스가 아닌 숫자를 인자로 받아 렌더를 시키는 방식이다.
정리하자면 react-native-snap-carousel
은 데이터의 인덱스를 이용하여 요소를 렌더하는 방식이다. 우리 프로젝트처럼 유동성있는 데이터가 아닌 불변하는, 혹은 변하더라도 이전의 것에 변화를 주지않는 방식을 사용해야 가능하다.
결국 react-native-snap-carousel
사용은 포기하고 마커를 클릭하면 컴포넌트에 데이터들을 props
로 내려주어 해당 데이터에 관한 정보를 렌더하도록 수정했다. 프로젝트 기간 중 많은 기간을 쏟아 구현하려던 기능이었는데 내 손으로 날려버리니 아쉬움과 약간의 후련함이 있었다. 여기에 많은 시간을 쏟은 만큼 이제 다른 기능들을 빠르게 구현해야 한다.