yarn install react-query
npm install @react-navigation/native
https://data.seoul.go.kr/dataList/OA-15486/S/1/datasetView.do <=API키 받기
react navigation
react-query
map
Main.jsx
import { useQuery, useQueryClient } from "react-query";
import Slide from "../components/Main/Slide";<= 컴포넌트 파일
import VCard from "../components/Main/VCard";<= 컴포넌트 파일
import HCard from "../components/Main/HCard";<= 컴포넌트 파일
export default function Main({ navigation: { navigate } }) {
const { data: getEventListsData, isLoading: isLoadingEL } = useQuery(
["Mains", "getEventLists"],
getEventList
);
return (
<FlatList
numColumns={2}
refreshing={isRefreshing}
onEndReachedThreshold={1}
onRefresh={onRefresh}
ListHeaderComponent={
<>
<Swiper height="100%" showsPagination={false} autoplay loop>
{getEventListsData.culturalEventInfo.row.map((realtime) => (
<Slide
key={imgId(realtime.MAIN_IMG)}
realtime={realtime}
navigate={navigate}
imgId={imgId}
/>
))}
}
Slide.jsx
import React from 'react';
import styled from '@emotion/native';
import { useNavigation } from '@react-navigation/native';
import Detail from '../../pages/Detail';
import { useQuery } from 'react-query';
import { getEventList } from '../../api';
import { View } from 'react-native';
export default function HCard({ realtime, imgId }) {
const { navigate } = useNavigation();
return (
<HWrapper>
<UpcomingRow
onPress={() =>
navigate('Stacks', {
screen: 'Detail',
params: {
itemId: imgId(realtime.MAIN_IMG),
main_img: realtime.MAIN_IMG,
codename: realtime.CODENAME,
title: realtime.TITLE,
date: realtime.DATE,
target: realtime.USE_TRGT,
target_fee: realtime.USE_FEE,
place: realtime.PLACE,
link: realtime.ORG_LINK,
program: realtime.PROGRAM,
},
})
}
>
<UpcomingPoster source={{ uri: realtime.MAIN_IMG }} />
<UpcomingColumn>
<UpcomingTitle>{realtime.TITLE}</UpcomingTitle>
<Release>~ {realtime.DATE.split('~')[1]}</Release>
</UpcomingColumn>
</UpcomingRow>
</HWrapper>
);
}
const HWrapper = styled.View`
width: 50%;
align-items: center;
`;
const UpcomingRow = styled.TouchableOpacity`
align-items: flex-start;
margin-bottom: 10px;
/* background-color: blue; */
/* flex: 1; */
`;
const UpcomingPoster = styled.Image`
width: 190px;
height: 200px;
background-color: grey;
border-radius: 5px;
`;
const UpcomingOverview = styled.Text`
font-size: 15px;
line-height: 20px;
font-weight: 500;
margin-top: 5px;
margin-bottom: 5px;
color: ${(props) => props.theme.pointText};
`;
const UpcomingColumn = styled.View``;
const Release = styled.Text`
font-size: 13px;
font-weight: 500;
color: ${(props) => props.theme.pointTextGray};
/* margin: 10px 0; */
`;
const UpcomingTitle = styled.Text`
font-family: 'twayair';
font-size: 18px;
letter-spacing: -1.3px;
font-weight: 600;
padding: 15px 20px 8px 0;
color: ${(props) => props.theme.pointText};
`;
const UpcomingView = styled.View``;