[ React Native 영화 페이지 UI 만들기]
화면과 이미지를 겹치게 하고 싶을 떄
-> style={StyleSheet.absoluteFill}
height="100%" -> 자식이 가진 크기만큼만
--> 이미지 스타일 width, height 값 안 넣어주면 화면에 이미지 안 보임..
<Swiper>
<SwiperChildView>
</SwiperChildView>
</Swiper>
-> 화면 꽉 채움 -> Swiper에 height 100% 주기
<Swiper height="100%"> // => showPagination, autoplay, loop 등등 추가 가능
<SwiperChildView>
</SwiperChildView>
<SwiperChildView>
</SwiperChildView>
<SwiperChildView>
</SwiperChildView>
</Swiper>
------
<SwiperChildView>
<BackgroundImg key={movie.id} style={StyleSheet.absoluteFill} source={{ uri: getImgPath(movie.backdrop_path) }} />
<LinearGradient style={StyleSheet.absoluteFill} colors={["transparent", "black"]} />
<Row>
<Poster source={{ uri: getImgPath(movie.poster_path) }} />
<Column>
<Title>{movie.title}</Title>
<Rating>⭐{movie.vote_average}</Rating>
<Overview>
{movie.overview.slice(0, 150)}
{movie.overview.length > 150 && "..."}
</Overview>
</Column>
</Row>
</SwiperChildView>
const SwiperChildView = styled.View`
flex: 1;
justify-content: flex-end;
height: ${SCREEN_HEIGHT / 3 + "px"};
background-color: green;
`;
const BackgroundImg = styled.Image`
height: 100%;
width: 100%;
`;
const Row = styled.TouchableOpacity`
flex: 1;
flex-direction: row;
align-items: flex-end;
`;
const Column = styled.View`
width: 65%;
margin-left: 10px;
margin-bottom: 10px;
`;
const Poster = styled.Image`
width: 100px;
height: 160px;
margin-left: 10px;
margin-bottom: 10px;
`;
const Title = styled.Text`
font-size: 20px;
font-weight: 600;
color: white;
`;
const Rating = styled.Text`
color: white;
margin-top: 5px;
margin-bottom: 5px;
`;
const Overview = styled.Text`
font-size: 12px;
color: white;
`;
스타일 컴포넌트를 활용해서 UI 구성, react-native에서 import 안 되도 가능
API 연결
async, await, fetch
useEffect, callback, dependency array
-----
const getNoWPlayings = async () => {
const { results } = await fetch(`${BASE_URL}/now_playing?api_key=${API_KEY}&language=en-US&page=1`).then((res) => res.json());
setNowPlayings(results);
setIsLoading(false);
};
useEffect(() => {
getNoWPlayings();
}, []);
if (isLoading) {
return (
<Loader>
<ActivityIndicator />
</Loader>
);
}
=> "https://api.themoviedb.org/3/movie/now_playing?api_key=5f416eba9f9b0006b7c1c5159f9a73dd&language=en-US&page=1" 대신 함수 BASE_URL, API_KEY를 ${ }에 넣어주기( + 백틱)
<ScrollView>
<Swiper height="100%" showsPagination={false}>
{nowPlayings.map((movie) => (
<SwiperChildView>
</SwiperChildView>
))}
</Swiper>
</ScrollView>
=> 서버에서 받아온 데이터로 맵 함수를 돌려주고, 이미지 uri는 results 객체 이용
const getData = async () => {
await Promise.all([getNowPlayings(), getTopRated(), getUpcoming()]);
};
getNowPlayings(), getTopRated(), getUpcoming()
-> 이 세 가지 API 요청이 끝나야 실행, 그리고 setIsLoading 실행
----
[RefreshControl]
const [refreshing, setRefreshing] = React.useState(false);
const onRefresh = React.useCallback(() => {
setRefreshing(true);
wait(2000).then(() => setRefreshing(false));
}, []);
<ScrollView
contentContainerStyle={styles.scrollView}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
/>
---------
[FlatList]
- ScrollView 모든 리스트들을 한번에 렌더링 해야해서 리스트가 많을 수록 성능이 저하됩니다.
- FlatList는 화면에 보이지 않는 리스트들은 메모리에서 제거하고 화면에 보이는 부분들만 렌더링하여 리스트가 많이 있어도 성능 저하를 최소화 시킵니다. (무한스크롤 적용에 적합!)
<FlatList> : 자식 컴포넌트 X => <FlatList /> + props를 사용함
데이터 : 배열,
render Item : map함수로 뿌려주는 대신 -> renderItem({item, index, separators}); // callback함수로 표현
<FlatList data={} renderItem={} keyExtractor={} /> // keyExtractor : key 보관
---
<FlatList data={topRateds} renderItem={({item}) => (
<HCard movie={item} />
)} keyExtractor={item=>item.id} />
매개변수는 객체, item으로
ItemSeparatorComponent={<View style={{ width: 10 }} />}
-> 카드 각각 거리 띄우기
--
ListHeaderComponent, ListFooterComponent
<FlatList
refreshing={isRefreshing}
onRefresh={onRefresh}
ListHeaderComponent={
<>
<Swiper height="100%" showsPagination={false}>
{nowPlayings.map((movie) => (
<Slide key={movie.id} movie={movie} />
))}
</Swiper>
<ListTitle>Top Rated Movies</ListTitle>
<FlatList
horizontal
contentContainerStyle={{ paddingHorizontal: 20 }}
showsHorizontalScrollIndicator={false}
data={topRateds}
renderItem={({ item }) => <VCard movie={item} />}
keyExtractor={(item) => item.id}
ItemSeparatorComponent={<View style={{ width: 10 }} />}
/>
<ListTitle>Upcoming Movies</ListTitle>
</>
}
data={upcomings}
renderItem={({ item }) => <HCard movie={item} />}
keyExtractor={(item) => item.id}
ItemSeparatorComponent={<View style={{ height: 10 }} />}
/>
FlatList에서는 refreshControl이 기본으로 내장되어있음
-----
구조분해할당