React Native에서 Navigation 효과 만들기(feat. Expo)

그래도 아무튼 개발자·2023년 3월 12일
0

React / React-Native

목록 보기
3/6
post-thumbnail

React Native를 활용하여 어플을 만드는 과정에서 화면 전환효과(Navigation)은 필수적으로 포함된다.
다양한 Navigation이 있지만 여기서는 Stack Navigation을 활용하였다.

import { StatusBar } from 'expo-status-bar';
import React, { useState, useRef, useEffect } from 'react';
import { StyleSheet, Text, View, ScrollView, Image, Dimensions } from 'react-native';
import Task2 from './components/Task2';
import Task from './components/Task';
import Login from './components/Login';
import { initializeApp } from "firebase/app";
import { getDatabase, ref, onValue, set, orderByChild, query } from 'firebase/database';
import VideoScreen from './components/VideoScreen';
import VideoScreen2 from './components/VideoScreen2';
import VideoScreen3 from './components/VideoScreen3';
import VideoScreen4 from './components/VideoScreen4';
import VRVideoScreen from './components/VRVideoScreen';
import { NavigationContainer, StackActions } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createAppContainer } from 'react-navigation';

import Page from './components/Page';
import { Camera } from 'expo-camera';
import Cam from './components/Camera';

const app = initializeApp(firebaseConfig);

const Stack = createNativeStackNavigator();



const MyStack =() => {
  return(
    <NavigationContainer>
    <Stack.Navigator>
      

      
      <Stack.Screen 
        name  = "로그인" 
        component={Login}
        options = {{
          title: 'LOGIN',
          headerStyle:{
            backgroundColor: 'black', },
          headerTintColor: 'white',
          headerTitleAlign: 'center'

        }}/>
        <Stack.Screen 
        name  = "Task2" 
        component={Task2}
        options = {{
          title: 'WEPO',
          headerStyle:{
            backgroundColor: 'black', },
          headerTintColor: 'white',
          headerTitleAlign: 'center'
          }}/>
        <Stack.Screen 
        name  = "Task" 
        component={Task}
        options = {{title: 'Task'}}/>
        <Stack.Screen 
        name  = "Vid" 
        component={VideoScreen}
        options = {{title: 'Video'}}/>
        <Stack.Screen
        name="Vid2"
        component={VideoScreen2}
        options={{ title: 'Video2' }} />
        <Stack.Screen
        name="Vid3"
        component={VideoScreen3}
        options={{ title: 'Video3' }} />
        <Stack.Screen
        name="Vid4"
        component={VideoScreen4}
        options={{ title: 'Video4' }} />
        <Stack.Screen
        name="VR"
        component={VRVideoScreen}
        options={{ title: 'VR' }} />
        <Stack.Screen
        name  = "Cam" 
        component={Cam}
        options = {{title: 'Camera'}}/>
      
      
    </Stack.Navigator>
  </NavigationContainer>




    
  );
}

export default MyStack;

App.js 파일 내용이다.

import { StatusBar } from 'expo-status-bar';
import React, { useState, useRef, useEffect } from 'react';
import { TextInput, SafeAreaView, Button, StyleSheet, Text, View, FlatList, TouchableOpacity, ScrollView } from 'react-native';
import { initializeApp } from "firebase/app";

import { NavigationContainer } from '@react-navigation/native';


import { getDatabase, ref, onValue, set, orderByChild, query } from 'firebase/database';
const firebaseConfig = {
    apiKey: "----------------------------------",
    authDomain: "----------------------------------",
    projectId: "----------------------------------",
    storageBucket: "----------------------------------",
    messagingSenderId: "----------------------------------",
    appId: "----------------------------------"
};

const app = initializeApp(firebaseConfig);


const Task2 = ({navigation}) => {

    const text1 = useRef(null);

    const [text, setText] = useState('');
    const [data, setData] = useState('');

    function delData(key) {
        const db = getDatabase();
        const reference = ref(db, 'users/' + key);
        set(reference, null);
    }

    function saveData() {
        var key = Math.random().toString(16).replace(".", "");
        var data = text;

        const db = getDatabase();
        const reference = ref(db, 'users/' + key);
        set(reference, {
            data: data,
            regdate: new Date().toString()
        });

        text1.current.clear();
    }


    const renderItem = ({ item }) => {
        return (
            <View style={{ padding: 5, borderBottomColor: '#aaa', borderBottomWidth: 1, flexDirection: 'row', }}>
                <TouchableOpacity>
                    <Text onPress={() => navigation.navigate("Vid")} style={{ flex: 1, fontSize: 20 }}>
                        {(() => {
                            if (item.data === "락 세팅") return item.data;
                        })()}
                    </Text>
                    <Text onPress={() => navigation.navigate("Vid2")} style={{ flex: 1, fontSize: 20 }}>
                        {(() => {
                            if (item.data === "크로스피스 세팅") return item.data;
                        })()}
                    </Text>
                    <Text onPress={() => navigation.navigate("Vid3")} style={{ flex: 1, fontSize: 20 }}>
                        {(() => {
                            if (item.data === "스크류잭 세팅") return item.data;
                        })()}
                    </Text>
                    <Text onPress={() => navigation.navigate("Vid4")} style={{ flex: 1, fontSize: 20 }}>
                        {(() => {
                            if (item.data === "크로스 가이딩 슬라이드 세팅") return item.data;
                        })()}
                    </Text>
                </TouchableOpacity>

                <SafeAreaView style={{ flex:1,
                    justifyContent: "flex-end",
                    alignItems: 'flex-end' }}>
                    <Button title="삭제" color='red' onPress={() => delData(item.key)} />
                </SafeAreaView>
            </View>

        )
    }

    useEffect(() => {

        const db = getDatabase();
        const reference = query(ref(db, 'users'), orderByChild('regdate'));

        onValue(reference, (snapshot) => {
            console.log(snapshot);

            const tmp = [];

            snapshot.forEach((child) => {
                tmp.unshift({
                    key: child.key,
                    data: child.val().data,
                    regdate: child.val().regdate,
                });
            });

            console.log(tmp);
            setData(tmp);
        });

    }, [])

    return (
        <ScrollView>
            <View style={{  flex: 1 }}>
                <StatusBar style="auto" />
                <SafeAreaView style={{ flex: 1 }}>
                    <View style={{ padding: 15 }}>
                        <Text style={styles.title}>부품 리스트</Text>
                    </View>
                    <View style={{ backgroundColor: "white", flex: 1 }}>
                        <View style={{ flexDirection: 'row', padding: 10 }}>
                            <TextInput style={{ backgroundColor: "#f2f2f2", padding: 5, flex: 1 }}
                                ref={text1}
                                onChangeText={text => setText(text)} placeholder="부품을 입력하세요." multiline/>

                                <Button title="추가" onPress={() => saveData()} />
                        </View>
                        <View>
                            
                            <FlatList 
                                data={data}
                                    renderItem={renderItem} style={{ padding: 10 }} />
                            
                        </View>
                        
                    </View>

                </SafeAreaView>
            </View>
        </ScrollView>
    );
}

여긴 Task2.js 파일의 내용이다

App.js파일에서 MyStack의 Stack.Navigator를 통해 각 js파일의 stack screen Name을 지정해주었고, 아래 Task2.js 파일에서는 버튼을 눌렀을 때 Navigation이 해당 js파일로 이동되어 실행되도록 하는 문구가 담겨있다.

실행결과는 다음과 같다.
https://blog.naver.com/cline1103/222848124845

버튼을 누르는 순간과 동시에 왼쪽 위에 뒤로 갈수있는 버튼 또한 생겨난 것을 확인할 수 있다. 말 그대로 Stack형식처럼 계속 쌓이는 Navigation이기 때문에 대형 어플에서는 단점으로 작용할 수도 있다. 하지만 간단한 어플에서는 이것보다 좋은게 없다..

0개의 댓글