DetailPage(1.typescript, 2.navigation, 3.setOPtions, 4.route, 5.params, 6.useQuery, 7.Linking, 8.LinearGradient),

김종민·2022년 4월 10일
0

React-Native(1. Movie)

목록 보기
17/20

1.DetailPage.

1-1. 전체코드.

import React, { useEffect } from 'react'
import { Dimensions, StyleSheet, Linking } from 'react-native'
import styled from 'styled-components/native'
import { Movie, moviesApi } from '../api'
import Poster from '../components/Poster'
import { makeImgPath } from '../util'
import { LinearGradient } from 'expo-linear-gradient'
import { useQuery } from 'react-query'
import { Loader } from './Movie'
import { Ionicons } from '@expo/vector-icons'

const { height: SCREEN_HEIGHT } = Dimensions.get('window')
const Container = styled.ScrollView`
  background-color: black;
`
const Header = styled.View`
  height: ${SCREEN_HEIGHT / 4}px;
  justify-content: flex-end;
  padding: 0px 20px;
`
const Background = styled.Image``

const Column = styled.View`
  flex-direction: row;
`
const Title = styled.Text`
  color: white;
  font-size: 36px;
  align-self: flex-end;
  width: 80%;
  margin-left: 15px;
  font-weight: 500;
`
const Overview = styled.Text`
  color: white;
  margin-top: 30px;
  padding: 0px 20px;
  margin-bottom: 20px;
`
const VideoBtn = styled.TouchableOpacity`
  flex-direction: row;
`
const BtnText = styled.Text`
  color: white;
  font-weight: 600;
  margin-bottom: 10px;
  margin-left: 10px;
  line-height: 24px;
`
const Data = styled.View``
type RootStackParamList = {
  Detail: Movie
}

type DetailScreenProps = NativeStackScreenProps<RootStackParamList, 'Detail'>

const Detail: React.FC<DetailScreenProps> = ({
  navigation: { setOptions },
  route: { params },
}) => {
  const { isLoading, data, refetch } = useQuery(
    ['movies', params.id],
    moviesApi.detail,
    { enabled: 'original_title' in params }
  )
  console.log(data)
  useEffect(() => {
    setOptions({
      title: params.original_title,
    })
  }, [])
  const openTYLink = async (videoID: string) => {
    const baseUrl = `http://m.youtube.com/watch?v=${videoID}`
    await Linking.openURL(baseUrl)
  }
  return (
    <Container>
      <Header>
        <Background
          style={StyleSheet.absoluteFill}
          source={{ uri: makeImgPath(params.backdrop_path || '') }}
        />
        <LinearGradient
          colors={['transparent', 'gray']}
          style={StyleSheet.absoluteFill}
        />
        <Column>
          <Poster path={params.poster_path || ''} />
          <Title>{params.title}</Title>
        </Column>
      </Header>
      <Data>
        <Overview>{params.overview}</Overview>
        {isLoading ? <Loader /> : null}
        {data?.videos?.results?.map((video) => (
          <VideoBtn key={video.key} onPress={() => openTYLink(video.key)}>
            <Ionicons name="logo-youtube" color="white" size={24} />
            <BtnText>{video.name}</BtnText>
          </VideoBtn>
        ))}
      </Data>
    </Container>
  )
}

export default Detail

1. typescript check!!

  1. type RootStackParamList = { Detail: Movie }
    ==>ai.ts 에서 만들었던 interface Movie를 타입으로 불러온다.
    여기서 받는 params가 Movie에서 오기 떄문이다.

2.type DetailScreenProps = NativeStackScreenProps<RootStackParamList, 'Detail'>
==>위의 Root~~타입을 받아서 추가한다 StackScreenProps를

  1. const Detail: React.FC 로 type을 마무리한다.

2. navigation check!!(무지하게 중요함. page간 이동시 data,param전달!!)

2-1.data 및 params 주고 받는 방법.(in Component)
보내기.

Movie.tsx

Check!!
Movie.tsx에서 fullData={movie} <---- Slide Component에 movie data를 통으로 보내줌,

slide.tsx

interface SlideProps{ fullData:Movie} <---여기에 담아서 보냄.

const Slide:React.Fc=>({fullData}) => {
const navigation = useNavigation() <===useNavigation()을 사용함.
const gotoDateail = () => {
navigation.navigate('Stack', {
screen: 'Detail',
params: {...fullData}, } ) ===>'Stack' nav의 Detail Screen으로 fullData를 params에 담아서 보냄.
console.log(params)로 data확인해 볼것.

여기서 fillData는 Movie.tsx --> Slide.tsx로 보내지는 Data임.

return(

==>이 이벤트로 실행(TouchableOpacity 하지 않는 이유는 layout깨지는 거 막음.>

2-2. data받기.

in DetailPage.tsx.

const Detail:Re~~~  => ({ route:{params}) => {}

로 받아서 사용~
navigation: { setOptions}를 사용해서
header부분의 title을 변경가능,
check! (params.original_title)

params.id를 이용해 useQuery를 이용해서 해당movie의 detail info를 불러와서
data에 담음.

params로 받은 data는 param.~~~로 사용함.


                                                 

2-3. FlasList에서 Detailpage로 params보내는 방법

check!!!
FlatList에서는 item으로 다 받으니, params:{...item} 으로 보낸다.
여러 data를 한꺼번에 보내기 떄문에 반드시 ... 를 item앞에 붙여주어야함.

3. Linking( ex.youtube로 연결)

check!! api.ts에 datail APi 만듬.. movie.id(params.id)를 받아서 req 날림

detailPage.tsx 에서 useQuery사용해서 detail API호출(param.id 를 detail API에 보냄.)

const openTYLink 함수 만듬. video.key 를 videoID로 받음.
check!! console.log(data)로 data 모양 확인할것

import {Linking} from 'react-native' 확인할것

4.LinearGradient(배경화면 Grandient)효과.

실제적용사례~~

이번 포스터 마무으리~
profile
코딩하는초딩쌤

0개의 댓글