본문 바로가기

코딩 개발일지

[개발일지]스파르타코딩클럽_앱개발 종합반 3-5

//이제 뭔가 확실히 복잡해져서 정리가 잘 안된다 머리도 정리할겸 개발일지를 작성하며 이해하려한다

스택네비게이션. createStackNavigator 사용하기

 

이젠 이해도 힘들고 공식문서를 봐도 영어라서 더 쉽지 않다

공식문서 참고 https://reactnavigation.org/docs/tab-based-navigation

------------------------------------------

순서 1 - 설치

리액트 네비게이션 설치. 터미널창에 yarn add @react-navigation/stack 입력해서 설치한다.

//난 여기서 오류가 떠서 어쩔줄 몰라하던차에 즉문즉답 게시판에 가서 검색해보니

나랑 똑같은 오류를 겪는사람의 질문 답변이 bable.config.js 파일 내용을

//bable.config.js 내용을 이렇게 바꾸니 오류 해결됨

module
.exports = function(api) {

 
  api.cache(true);
 
  return {
  presets: ["babel-preset-expo"],
  presets: ["module:metro-react-native-babel-preset"],
  plugins: ["react-native-reanimated/plugin"],
  };
  };

이렇게 바꾸라고 하는 부분이 있어서 나도 적용해보니 해결됬다.

-------------------------

순서 2 - navigation 폴더 - StackNavigator.js 파일 생성

navigation 폴더 하나를 만들고 StackNavigator.js 파일을 만들어주고 아래 코드를 넣자

import React from 'react';
//설치한 스택 네비게이션 라이브러리를 가져옵니다
import { createStackNavigator } from '@react-navigation/stack';
 
//페이지로 만든 컴포넌트들을 불러옵니다
import DetailPage from '../pages/DetailPage';
import MainPage from '../pages/MainPage';
 
//스택 네비게이션 라이브러리가 제공해주는 여러 기능이 담겨있는 객체를 사용합니다
//그래서 이렇게 항상 상단에 선언하고 시작하는게 규칙입니다!
const Stack = createStackNavigator();
 
const StackNavigator = () =>{
    return (
        //컴포넌트들을 페이지처럼 여기게끔 해주는 기능을 하는 네비게이터 태그를 선언합니다.
        //위에서 선언한 const Stack = createStackNavigator(); Stack 변수에 들어있는 태그를 꺼내 사용합니다.
        //Stack.Navigator 태그 내부엔 페이지(화면) 스타일링 있는 다양한 옵션들이 담겨 있습니다.
        <Stack.Navigator
            screenOptions={{
                headerStyle: {
                    backgroundColor: "white",
                    borderBottomColor: "white",
                    shadowColor: "white",
                    height:100
                },
                //헤더의 텍스트를 왼쪽에 둘지 가운데에 둘지를 결정
                headerTitleAlign:'left',
                headerTintColor: "#000",
                headerBackTitleVisible: false
            }}
        >
            {/* 컴포넌트를 페이지로 만들어주는 엘리먼트에 끼워 넣습니다. 자체로 이제 페이지 기능을 합니다*/}
            <Stack.Screen name="MainPage" component={MainPage}/>
            <Stack.Screen name="DetailPage" component={DetailPage}/>
        </Stack.Navigator>
    )
}
export default StackNavigator;

//너무 잘 적혀있지만 한번더 적으면서 이해하기

import { createStackNavigator } from '@react-navigation/stack';

//좀전에 설치했던 리액트네비게이션에서 createStacknNavigator를 쓰겠다고 선언

 

import DetailPage from '../pages/DetailPage';

import MainPage from '../pages/MainPage';

//네비게이션을 쓸 대상 페이지 추가

 

const Stack = createStackNavigator();

//이건 고정으로 선언하고

 

const StackNavigator = () =>{

    return (

        <Stack.Navigator

            screenOptions={{

                headerStyle: {

                    backgroundColor: "white",

                    borderBottomColor: "white",

                    shadowColor: "white",

                    height:100 },

                headerTitleAlign:'left',

                headerTintColor: "#000",

                headerBackTitleVisible: false

            }}

        >

//이 부분이 컴포넌트를 페이지로 연결하는부분

            <Stack.Screen name="MainPage" component={MainPage}/>

            <Stack.Screen name="DetailPage" component={DetailPage}/>

        </Stack.Navigator>

    )}

export default StackNavigator;

 

-------------------------------------------

header[명사] 헤더(컴퓨터에서 출력될 때 각 페이지 맨 윗부분에 자동으로 붙는 부분) 

 

const StackNavigator 후에 첫번째<Stack.Navigator 이후 아래 스크린 옵션은 네비게이션 설정부분이고 header는 화면의 윗부분을 말하는것. 자세히보면 Stack.Navigator 안에 이 들어있는걸 볼수있다.

 

Stack.Navigator 이 더 큰범위이고 말하자면 책갈피, Stack.Screen는 책갈피 안에있는 페이지를 말함. 설정 부분은 공통으로 적용됨. Stack.Screen이름도 기본 컴포넌트와 같은 이름으로 만들어서 최대한 혼동이 없도록 이름을 지어준다

-----------------------------------------

순서 3 - App.js파일을 수정

import React from 'react';
//이제 모든 페이지 컴포넌트들이 끼워져있는 책갈피를 메인에 둘예정이므로
//컴포넌트를 더이상 불러오지 않아도 됩니다.
// import MainPage from './pages/MainPage';
// import DetailPage from './pages/DetailPage';
import { StatusBar } from 'expo-status-bar';
 
//메인에 세팅할 네비게이션 도구들을 가져옵니다.
import {NavigationContainerfrom '@react-navigation/native';
import StackNavigator from './navigation/StackNavigator'
 
export default function App() {
 
  console.disableYellowBox = true;
 
  return (
  <NavigationContainer>
    <StatusBar style="black" />
    <StackNavigator/>
 </NavigationContainer>);
}

기존에 페이지를 연결한것들이 주석처리 되어있다. 

import {NavigationContainerfrom '@react-navigation/native';

// 이건 기본으로 선언(네비게이션을 쓰려면 무조건 선언)

import StackNavigator from './navigation/StackNavigator'

// 위에서 만들었던 네비게이션폴더에 스택네비게이션 파일에서 선언했던 StackNavigator 를 가져옴

 

console.disableYellowBox = true

-> 이부분은 아이폰에서 노랑박스 오류창 뜨는거 없애는 부분이라 무시

 return (

 <NavigationContainer>

    <StatusBar style="black" />

    <StackNavigator/>

 </NavigationContainer>);

}

//맨위에 import 했던 import {NavigationContainerfrom '@react-navigation/native'

여기에서 네비게이션 컨테이너를 가져오고 그 안에 <StackNavigator/> 을 사용하는부분

이 부분을 '책'이라고 생각하고 그 내부에 <StackNavigator/> 여기를 페이지라고 생각하면됨

네비게이션컨테이너 모든 페이지를 return하는부분

---------------

여기서 의문! 여기까지 작성했을해서 돌리면 MainPage가 먼저 나오는데, 그 이유는 뭐지?

StackNavigator.js 파일에서 

            <Stack.Screen name="MainPage" component={MainPage}/>

            <Stack.Screen name="DetailPage" component={DetailPage}/>

        </Stack.Navigator>

MainPage가 위에 있어서인가?

-----------------------

-->>실험결과 정답인듯? (위아래 순서를 바꿔보니 온갖 에러가 다뜬다)

{/* 컴포넌트를 페이지로 만들어주는 엘리먼트에 끼워 넣습니다. 자체로 이제 페이지 기능을 합니다*/}

이렇게 친절하게 주석에 달아둔 말처럼 이 자체로 페이지 기능을 하는데 맨 위에꺼가 가장 앞 페이지 역할을 하는것 같다.

-------------------------

순서 4 - 페이지 이동하기

//navigation 객체가 가지고 있는 두 함수(setOptions navigate)
 
//해당 페이지의 제목을 설정할 수 있음
navigation.setOptions({
    title:'나만의 꿀팁'
 })
 
 //Stack.screen에서 name 속성으로 정해준 이름을 지정해주면 해당 페이지로 이동하는 함수
 navigation.navigate("DetailPage")
 
 //name 속성을 전달해주고, 두 번째 인자로 딕셔너리 데이터를 전달해주면, Detail 페이지에서
 //두번째 인자로 전달된 딕셔너리 데이터를 route 딕셔너리로 로 받을 수 있음
 navigation.navigate("DetailPage",{
   title: title
 })
 
  //전달받은 데이터를 받는 route 딕셔너리
 //비구조 할당 방식으로 route params 객체 키로 연결되어 전달되는 데이터를 꺼내 사용
 //navigate 함수로 전달되는 딕셔너리 데이터는 다음과 같은 모습이기 때문입니다.
 /*
   {
         route : {
             params :{
                 title:title
             }
         }
     }
 
 */
 const { title} = route.params;

먼저 이 4가지 기능에대해 확실히 기억해야한다.

 1) 네비게이터 이름 바꾸기 방법

위에서 컴포넌트를 페이지화하면서 스택.스크린에 네임을 MainPage로 지었다

<Stack.Screen name="MainPage" component={MainPage}/>

여기서 아무 제목을 변경 안하면 그냥 스택.스크린 네임 MainPage가 출력 되겠지만 어플을 쓸순 없으니 이름을 꼭 바꿔줘야한다 그래서 사용하는것이 navigation.setOptions({ title:'나만의 꿀팁' })


 2)  버튼을 눌러서 페이지를 이동하는 방법

navigation.navigate("DetailPage")

네비게이션.네비게이트("페이지주소") 직관적이다. 페이지 주소는 앞서 StackNavigator.js 에서 페이지화 했던부분

 <Stack.Screen name="DetailPage" component={DetailPage}/>  참고하면 된다

다만 이 방법은 데이터 없이 단순 페이지를 이동하는 방법이다.

 

3) 페이지 이동시 데이터도 함께 넘겨주며 이동하는 방법

navigation.navigate("DetailPage",{   title: title })

 

4) 넘겨준 데이터를 받는 코드

const { title} = route.params;

 

 -------------------------

MainPage.js 파일에서

export default function MainPage() {

기존에 이렇게 사용하던 부분 MainPage() 괄호부분이 수정된다

export default function MainPage({navigation,route}) {

navigation,route 딕셔너리 두개를 비구조할당방식으로 받아서 사용한다

 

--> 그런데 이 두개의 함수는 어디서 보내는걸까?  ->직관적으로 보내는곳이 없음

StackNavigator.js 파일에서

      <Stack.Screen name="MainPage" component={MainPage}/>

      <Stack.Screen name="DetailPage" component={DetailPage}/>          

</Stack.Navigator>

이부분을 보면 스택.네비게이터에서 스택.스크린에 컴포넌트 MainPage를 연결함으로써 이름 "MainPage"로 '페이지화' 시켰다.(혼동을 방지하기위해 같은 이름으로 짓지만 엄연히 다른종류)

Stack.Screen 으로 페이지화 당하면 두가지 딕셔너리를 사용할수 있다 (네비게이션, 라우트)

스택스크린에 컴포넌트가 연결되면 두개의 딕셔너리를 넘겨준다 (암기)

 

export default function MainPage({navigation,route}) {

-> 메인페이지가 스택.스크린으로 페이지화 당했으므로 navigation과 route를 사용할수 있음!

-----------------------------------------------------

 

MainPage.js

import React,{useState,useEffectfrom 'react';
import { StyleSheetTextViewImageTouchableOpacityScrollViewfrom 'react-native';
 
const main = 'https://storage.googleapis.com/sparta-image.appspot.com/lecture/main.png'
import data from '../data.json';
import Card from '../components/Card';
import Loading from '../components/Loading';
import { StatusBar } from 'expo-status-bar';
export default function MainPage({navigation,route}) {
 
  const [state,setState] = useState([])
  const [cateState,setCateState] = useState([])
  const [ready,setReady] = useState(true)
 
  useEffect(()=>{
    setTimeout(()=>{
        //헤더의 타이틀 변경
        navigation.setOptions({
          title:'나만의 꿀팁'
        })  
        setState(data.tip)
        setCateState(data.tip)
        setReady(false)
    },1000)
  },[])
 
  const category = (cate=> {
    if(cate == "전체보기"){
        setCateState(state)
    }else{
        setCateState(state.filter((d)=>{
            return d.category == cate
        }))
    }
}
  // let tip = state.tip;
  let todayWeather = 10 + 17;
  let todayCondition = "흐림"
  
  return ready ? <Loading/> :  (
 
    <ScrollView style={styles.container}>
      <StatusBar style="light" />
      {/* <Text style={styles.title}>나만의 꿀팁</Text> */}
       <Text style={styles.weather}>오늘의 날씨{todayWeather + '°C ' + todayCondition} </Text>
      <Image style={styles.mainImage} source={{uri:main}}/>
      <ScrollView style={styles.middleContainer} horizontal indicatorStyle={"white"}>
      <TouchableOpacity style={styles.middleButtonAll} onPress={()=>{category('전체보기')}}><Text style={styles.middleButtonTextAll}>전체보기</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton01} onPress={()=>{category('생활')}}><Text style={styles.middleButtonText}>생활</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton02} onPress={()=>{category('재테크')}}><Text style={styles.middleButtonText}>재테크</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton03} onPress={()=>{category('반려견')}}><Text style={styles.middleButtonText}>반려견</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton04} onPress={()=>{category('꿀팁 ')}}><Text style={styles.middleButtonText}>꿀팁 </Text></TouchableOpacity>
      </ScrollView>
      <View style={styles.cardContainer}>
         {/* 하나의 카드 영역을 나타내는 View */}
         {
          cateState.map((content,i)=>{
            return (<Card content={content} key={i} navigation={navigation}/>)
          })
        }
      </View>
    </ScrollView>)
}
 

4-1 먼저 이름 바꾸기방법

useEffect(()=>{

    setTimeout(()=>{

        //헤더의 타이틀 변경

        navigation.setOptions({

          title:'나만의 꿀팁'

        })  

        setState(data.tip)

        setCateState(data.tip)

        setReady(false)

    },1000)

이부분에  navigation.setOptions({title:'나만의 꿀팁' })  부분이 있는데 자세히 보면  setTimeout(()=>{

내부에 있는 코드라서 이 상태로 돌리면 1초 로딩동안은 타이틀명이 'MainPage'로 나오고 1초 후부터 타이틀이 '나만의 꿀팁'으로 변경된다 해당 코드를 setTimeout(()=>바깥에 배치하면 로딩창에서도 '나만의꿀팁' 타이틀을 볼수 있다.

--------------------------------

4-2 페이지이동하기

메인 화면에서 아래 나열된 카드를 클릭했을때 페이지가 바뀌도록 할것이다. 그 부분 코드는

<View style={styles.cardContainer}>

         {/* 하나의 카드 영역을 나타내는 View */}

         {

          cateState.map((content,i)=>{

            return (<Card content={content} key={i} navigation={navigation}/>)

          })

        }

      </View>

여기서 보면 cateState (= data.tip) 를 맵함수를 돌리는데 Card 컴포넌트 쪽으로 content를 넘겨준다. 코드를 자세히 보면 오류를 막기위해 key 인자값도 넘겨주고, navigation 이라는 이름으로 부여한 페이지를 이동할수있는 navigation 도구 역시 넘겨준다.

Card.js를 보면

import React from 'react';
import {ViewImageTextStyleSheet,TouchableOpacityfrom 'react-native'
 
//MainPage 부터 navigation 속성을 전달받아 Card 컴포넌트 안에서 사용
export default function Card({content,navigation}){
    return(
        //카드 자체가 버튼역할로써 누르게되면 상세페이지로 넘어가게끔 TouchableOpacity 사용
        <TouchableOpacity style={styles.card} onPress={()=>{navigation.navigate('DetailPage',content)}}>
            <Image style={styles.cardImage} source={{uri:content.image}}/>
            <View style={styles.cardText}>
                <Text style={styles.cardTitle} numberOfLines={1}>{content.title}</Text>
                <Text style={styles.cardDesc} numberOfLines={3}>{content.desc}</Text>
                <Text style={styles.cardDate}>{content.date}</Text>
            </View>
        </TouchableOpacity>
    )
}
 
const styles = StyleSheet.create({
   
    card:{
      flex:1,
      flexDirection:"row",
      margin:10,
  //
이하 카드 스타일 꾸미는부분 생략

Card 컴포넌트 안의 내용을 보면 content,navigation 두개의 값을 넘겨받고 있다. 화면에 띄울 content정보와 화면을 이동시켜주는 기능 navigation 도구도 함께 넘겨받았다.

먼저 이 버튼부분 TouchableOpacity 에서 눌렀을때 <TouchableOpacity style={styles.card} onPress={()=>{navigation.navigate('DetailPage')}}이렇게 네비게이션.네비게이트('페이지주소')만 해버린다면 버튼을 누르면 그냥 DetailPage로 이동만 해버린다. (데이터 없이 단순 페이지 이동)

------------------------

여기서 잠깐/

navigation도구를 사용하려면 페이지화 되어 있어야 사용할수 있다고 했다. 앞에 StackNavigator.js 파일에서

<Stack.Screen name="MainPage" component={MainPage}/>

<Stack.Screen name="DetailPage" component={DetailPage}/>  

이렇게 메인페이지와 디테일 페이지 두개만 스택스크린으로 페이지화 시켰는데 어째서 Card.js에서 navigation 도구를 사용할수 있을까?

-> 페이지화 되어있는 메인페이지에서 return (<Card content={content} key={i} navigation={navigation}/>이렇게 Card 컴포넌트로 네비게이션 도구를 넘겨줬으므로 Card 컴포넌트에서도 그 기능을 사용할수 있다.

-----------------------------

4-3 데이터와 함께 페이지 이동

Card.js에서 <TouchableOpacity style={styles.card} onPress={()=>{navigation.navigate('DetailPage',content)}}>

이 부분을 보면 content 값도 함께 넘겨주고 있다.

매번 똑같은 DetailPage만 볼수 없으니 앞으로는 항상 이렇게 content값도 함께 넘겨줘야한다.

-----------------------------

4-4 받은 데이터 활용

먼저 DetailPage.js를 보자

import React,{useState,useEffectfrom 'react';
import { StyleSheetTextViewImageScrollView,TouchableOpacity,Alert,Share } from 'react-native';
import * as Linking from 'expo-linking';
 
export default function DetailPage({navigation,route}) {
 
    const [tipsetTip] = useState({
        "idx":9,
        "category":"재테크",
        "title":"렌탈 서비스 금액 비교해보기",
        "image": "https://storage.googleapis.com/sparta-image.appspot.com/lecture/money1.png",
        "desc":"요즘은 정수기, 공기 청정기, 자동차나 장난감 다양한 대여서비스가 활발합니다. 사는 것보다 경제적이라고 생각해 렌탈 서비스를 이용하는 분들이 늘어나고 있는데요. 다만, 이런 렌탈 서비스 이용이 하나둘 늘어나다 보면 금액은 겉잡을 없이 불어나게 됩니다. 특히, 렌탈 서비스는 빌려주는 물건의 관리비용까지 포함된 것이기에 생각만큼 저렴하지 않습니다. 직접 관리하며 사용할 있는 물건이 있는지 살펴보고, 렌탈 서비스 항목에서 제외해보세요. 렌탈 비용과 구매 비용, 관리 비용을 여러모로 비교해보고 고민해보는 것이 좋습니다. ",
        "date":"2020.09.09"
    })
   
    useEffect(()=>{
        console.log(route)
        navigation.setOptions({
            title:route.params.title,
            headerStyle: {
                backgroundColor: '#000',
                shadowColor: "#000",
            },
            headerTintColor: "#fff",
        })
        setTip(route.params)
    },[])
 
    const popup = () => {
        Alert.alert("팝업!!")
    }
 
    const share = () => {
        Share.share({
            message:`${tip.title} \n\n ${tip.desc} \n\n ${tip.image}`,
        });
    }
 
    const link = () => {
        Linking.openURL("https://spartacodingclub.kr")
    }
    return (
        // ScrollView에서의 flex 숫자는 의미가 없습니다. 정확히 보여지는 화면을 몇등분 하지 않고
        // 화면에 넣은 컨텐츠를 모두 보여주려 스크롤 기능이 존재하기 때문입니다.
        // 여기선 내부의 컨텐츠들 영역을 결정짓기 위해서 height 값과 margin,padding 값을 적절히 이용해야 합니다.
        <ScrollView style={styles.container}>
            <Image style={styles.image} source={{uri:tip.image}}/>
            <View style={styles.textContainer}>
                <Text style={styles.title}>{tip.title}</Text>
                <Text style={styles.desc}>{tip.desc}</Text>
                <View style={styles.buttonGroup}>
                    <TouchableOpacity style={styles.button} onPress={()=>popup()}><Text style={styles.buttonText}> 찜하기</Text></TouchableOpacity>
                    <TouchableOpacity style={styles.button} onPress={()=>share()}><Text style={styles.buttonText}> 공유하기</Text></TouchableOpacity>
                    <TouchableOpacity style={styles.button} onPress={()=>link()}><Text style={styles.buttonText}>외부 링크</Text></TouchableOpacity>
                </View>
               
            </View>
           
        </ScrollView>
   
    )
}
 
const styles = StyleSheet.create({
    container:{
        backgroundColor:"#000"
    },
    image:{
        height:400,
        margin:10,
        marginTop:40,
        borderRadius:20
    },
    textContainer:{
        padding:20,
        justifyContent:'center',
        alignItems:'center'
    },
    title: {
        fontSize:20,
        fontWeight:'700',
        color:"#eee"
    },
    desc:{
        marginTop:10,
        color:"#eee"
    },
    buttonGroup: {
        flexDirection:"row",
    },
    button:{
        width:90,
        marginTop:20,
        marginRight:10,
        marginLeft:10,
        padding:10,
        borderWidth:1,
        borderColor:'deeppink',
        borderRadius:7
    },
    buttonText:{
        color:'#fff',
        textAlign:'center'
    }
})

함수 부분을 보면 export default function DetailPage({navigation,route}) {

이렇게 보통 비어있던 괄호 부분에 function DetailPage() { 네비게이션과 라우트를 사용하는걸 볼수있다. 이유는?

앞서 StackNavigator.js 파일에서 MainPage와 함께 페이지화 했기 때문에 그대로 사용할수 있는것이다.

 

디테일 페이지 내에서 상태를 사용하기위해 const [tipsetTip] = useState({  내용 이렇게 먼저 선언했는데 내용 부분을 보면 기본값을 가지고 있다. 그 이유는, 아래에

useEffect(()=>{  가 있는데 useEffect는 화면이 그려지고 난 후에 실행되는 코드라는 것이다.

즉 위에 선언한 useState 인 tip에 아무런 (화면을 그려지게 만들) 데이터가 없다면 아래 

return (       

        <ScrollView style={styles.container}>

            <Image style={styles.image} source={{uri:tip.image}}/>

리턴문 이후 이미지를 생성하는데 uri로 tip이 들어가는데 초기엔 아무런 값이 없기 때문에 화면을 만들지 못해서 오류가 발생하게 될것이기 때문에 useState안에 초기 기본 데이터를 넣어준것이다. 혹은 로딩창을 구현한다면 문제는 해결될것 같다.

------------------

아무튼 useEffect(()=>부분을 다시 보면

console.log(route이 부분은 사용자 입장에선 필요 없는 부분이겠지만 이 코드는 교육용이기 때문에 route에 어떤 데이터를 전달받았는지 터미널 창에서 확인시켜주기위해 넣은 것이다.

------------------------

여기서 화면에 카드를 클릭해보면 터미널창에 이런 내용이 올라온다.

"key": "DetailPage-8zYZydP-6J-rrb5E9khYf",
  "name": "DetailPage",
  "params": Object {
    "category": "
반려견",
    "date": "2020.09.09",
    "desc": "
우선, 배변패드를 순서대로 돌며 간식을 조금씩 떨어뜨려 놓는다. 2단계는 배변패드 앞에서 기다렸다 반려견이 스스로 올라오면
 
간식을 주어서 보상하고, 3단계는 “화장실 가자”나 “매트” 같은 명령어를 붙여 말한 뒤 배변패드에 올라오면 간식을 주는 것이다. 마지막 단
계는 배변패드에 올라간 반려견이 대소변을 본 다음 간식을 줌으로써 이 장소가 즐거운 곳이라는 인식을 심어주는 것이다. 그리고 무엇보다 1, 2회 사용한 배변패드는 바로 갈아줘야 한다.",
    "idx": 6,
    "image": "
https://storage.googleapis.com/sparta-image.appspot.com/lecture/puppy.png",
    "title": "
반려견에게 배변 교육 시킬 때",
  },
  "path": undefined,
}

즉 앞서 Card.js에서 넘겨보낸 content의 데이터들이 route에 다 들어가 있는걸 볼수 있다. 그런데 자세히 보면 우리가 사용할 넘겨보냈던 데이터는 "params" 안에 다 들어가 있으므로 우리가 데이터를 사용할땐 route.params.xxxx 를 사용해서 원하는 데이터를 뽑아 쓸수 있다.

-------------------------

navigation.setOptions({

            title:route.params.title,

아까 배웠던 navigation.setOptions 이다. 해당 페이지의 제목을 바꿔준다. title : route.parms.title 이렇게 적혀 있는데 즉 위에 터미널에서 본 Card.js에서 넘겨받은 content 데이터에서 title 부분으로 제목을 바꾼다.

이후 headerStyle: {  등 으로 자체 타이틀 부분을 꾸며줄수 있고 아래에 setTip(route.params)

을 사용하면서 드디어 tip에 Card.js에서 넘겨받은 데이터를 tip에 넣어준다.

다시 return문으로 내려가면 이제는 tip에 데이터가 있기때문에

return (     

        <ScrollView style={styles.container}>

            <Image style={styles.image} source={{uri:tip.image}}/>         // ~이하생략

 

문제없이 넘겨받은 자료로 화면을 그려주게 된다.

 

-------------------------

이번 강의 3-5 역시도 참 어려웠다.

강의를 한번 더 들으면서 하나하나 순서대로 머리속에 정리를 하면서 진행하니까 이해가 된다.

막상 이해가 되고나니까 그렇게 어려운게 아니라는 생각이 드는데 완벽하게 이해가 안된 상태에서 대충 넘어가려고 하면 이후로는 아무것도 할수 없을것 같다.