React-Native [7. React Navigation으로 페이지 이동하기]

앱에서 만든 컴포넌트들을 페이지화 시켜주고, 해당 페이지끼리 이동을 가능하게 해주는 라이브러리!
Expo에서 제공하고 있다.

1) React Navigation

설치코드

yarn add @react-navigation/native

expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

2) Stack Navigator

컴포넌트에 페이지 기능 부여.
컴포넌트 -> 컴포넌트 이동 가능케함
=> 페이지 이동 기능!

설치코드

yarn add @react-navigation/stack

예시코드

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
                },
                headerTintColor: "#000",
                headerBackTitleVisible: false
            }}
            
        >

            {/* 컴포넌트를 페이지로 만들어주는 엘리먼트에 끼워 넣습니다. 이 자체로 이제 페이지 기능을 합니다*/}
            <Stack.Screen name="MainPage" component={MainPage}/>
            <Stack.Screen name="DetailPage" component={DetailPage}/>
        </Stack.Navigator>
    )
}

export default StackNavigator;

사용법

  1. createStackNavigator 라이브러리를 먼저 가져오고, Stack에 그 라이브러리를 선언한다!
  2. Stack.Navigator를 선언하고, 그 안에 각 페이지를 component로 넘기는 Stack.Screen를 선언한다.

가장 먼저 선언한 Stack.Screen이 화면에 보이게 된다!

3) Navigation Container

예시코드

App.js

import React from 'react';
//이제 모든 페이지 컴포넌트들이 끼워져있는 책갈피를 메인에 둘예정이므로
//컴포넌트를 더이상 불러오지 않아도 됩니다.
// import MainPage from './pages/MainPage';
// import DetailPage from './pages/DetailPage';
import { StatusBar } from 'expo-status-bar';

//메인에 세팅할 네비게이션 도구들을 가져옵니다.
import {NavigationContainer} from '@react-navigation/native';
import StackNavigator from './navigation/StackNavigator'

export default function App() {

  console.disableYellowBox = true;

  return ( 
  <NavigationContainer>
    <StatusBar style="black" />
    <StackNavigator/>
 </NavigationContainer>);
}

사용법

  1. NavigationContainer와 StackNavigator 라이브러리를 선언한다!
  2. return 되는 부분을 NavigationContainer로, 그리고 그 안에 StackNavigator를 선언한다!

4) navigation.navigate()

예시코드

Mainpage.js

.
.
.

<View style={styles.cardContainer}>
        {cateState.map((content, i) => {
          return <Card content={content} key={i} navigation={navigation}/>;
        })}
</View>

.
.
.
Card.js

.
.
.

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>
    )
}

.
.
.

사용법

  1. 페이지를 이동시키는 역할을 하는 컴포넌트로 content와 navigation을 넘겨준다!
  2. TouchableOpacity(버튼역할)가 이미 가지고있는 onPress함수에 화살표함수
()=>{navigation.navigate('이동할 페이지',content)}

를 선언하면, 이동할 페이지에 해당하는 데이터가 전달되며 페이지로 이동한다!

5) navigation, route

예시코드

Detail.js

import React,{useState,useEffect} from 'react';
import { StyleSheet, Text, View, Image, ScrollView,TouchableOpacity,Alert } from 'react-native';

export default function DetailPage({navigation,route}) {
		
		//초기 컴포넌트의 상태값을 설정
		//state, setState 뿐 아니라 이름을 마음대로 지정할 수 있음!
    const [tip, setTip] = 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)

	//Card.js에서 navigation.navigate 함수를 쓸때 두번째 인자로 content를 넘겨줬죠?
  //content는 딕셔너리 그 자체였으므로 route.params에 고대~로 남겨옵니다.
  //즉, route.params 는 content죠!

        navigation.setOptions({
						//setOptions로 페이지 타이틀도 지정 가능하고
            title:route.params.title,
						//StackNavigator에서 작성했던 옵션을 다시 수정할 수도 있습니다. 
            headerStyle: {
                backgroundColor: '#000',
                shadowColor: "#000",
            },
            headerTintColor: "#fff",
        })
        setTip(route.params)
    },[])

    const popup = () => {
        Alert.alert("팝업!!")
    }
    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>
                <TouchableOpacity style={styles.button} onPress={()=>popup()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>
            </View>
            
        </ScrollView>
    
    )
}

사용법

  1. 보여줄 페이지에 인자로 {navigation, route} 선언!
  2. useState로 초깃값 설정!그리고 route.params에 아까 건네준 content가 할당됨!
  3. useEffect
    1) navigation.setOptions에 title, headerStyle 등 변경!
    2) route.params로 초깃값을 가져온 content값으로 변경!

최종본

좋은 웹페이지 즐겨찾기