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이기 때문에 대형 어플에서는 단점으로 작용할 수도 있다. 하지만 간단한 어플에서는 이것보다 좋은게 없다..