Keyboard.dismiss()<Textinput>에 내용을 적을 시, 키보드가 튀어나오는데 해당 메소드를 쓰면 해당 내용을 작성하고 등록시, 키보드가 자동으로 사라짐.Logic
글 등록 -> 등록 버튼 클릭 -> 글이 등록되면서 모바일 키보드가 내려감.
expo에서 Routing 뿐만 아니라, navigation 레이아웃을 지원해주는 라이브러리다. sidebar, modal, deep linking 등등..
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { NavigationContainer } from "@react-navigation/native";
const Stack = createNativeStackNavigator();
// {navigation : {navigate}} << 지정한 컴포넌트로 이동하기. 해당 코드에서는 two 컴포넌트로 갈 것이다.
const One = ({ navigation: { navigate } }) => {
return (
<TouchableOpacity
onPress={() => {
return navigate("two");
}}>
<Text>One</Text>
</TouchableOpacity>
);
};
const Two = ({ navigation: { navigate, setOptions } }) => {
return (
<>
<TouchableOpacity onPress={() => navigate("three")}>
<Text>Two</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => setOptions({ title: "Hello, Jane Doe" })}>
<Text>Set Options</Text>
</TouchableOpacity>
</>
);
};
const Three = ({ navigation: { goBack, reset } }) => {
// 뒤로가기 속성 : goBack
return (
<>
<TouchableOpacity onPress={() => goBack()}>
<Text>Three</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => reset({ index: 0, routes: [{ name: "two" }] })}>
{/*reset은 navigation history 자체를 싹 다 밀어버림. history가 남아있는 경우, two에서 one으로 갈 수 있지만, 싹 다 밀어버렸기 때문에 two에서 뒤로가기 버튼이 없어짐.*/}
<Text>Reset Navigation</Text>
</TouchableOpacity>
</>
);
};
export default function App() {
return (
<NavigationContainer>
{/* initialRouteName는 첫 로딩이 끝나고, 화면에 표시되는 페이지를 지정. */}
{/*(<Stack.Navigator initialRouteName="three">*/}
{/* screenOptions 는 객체를 인자로 받음.*/}
<Stack.Navigator
screenOptions={{
headerTintColor: "red", // 헤더부분 색상 변경 속성
headerBackTitle: "뒤로 오십셔", // 뒤로가기 title 변경
presentation: "modal", // 페이지 이동 시, 모달형식으로 뜨게 할 지
animation: "flip", // 카드 형식으로 페이지 이동 효과 애니메이션
}}>
<Stack.Screen name="one" component={One} />
<Stack.Screen name="two" component={Two} />
<Stack.Screen
options={{ presentation: "modal" }}
// 개별적으로 option을 줄 수 있음.
// 일괄적으로 하려면 감싸고 있는 <Stack.Navigator>에 screenOptions={{ ... }} 적용.
name="three"
component={Three}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
// <Stack.Screen>에 props로 들어가는 컴포넌트를 '스크린 컴포넌트'라고 지칭한다.
// 해당 컴포넌트들은 기본적으로 navigation을 props를 가진다..
참고 블로그
React Native 프로젝트에서 React Navigation 중 Stack Navigation 을 사용하면 스택이 계속 쌓인다. 이 때 스택을 초기화 해야하는 경우가 있다. 대표적으로 step을 밟으면서 회원가입을 할 경우! 회원가입이 끝나고 난 뒤에도 뒤로가기를 했을때 회원가입 중인 페이지를 안 보이게 하려면 스택을 초기화해야한다.
navigation.reset({routes: [{name: "welcome", params: { email, password }}]})
// name 옆에는 지정해준 컴포넌트 이름, params 에는 다음 페이지로 보내줄 변수들을 입력. prams는 선택사항.
import React from 'react';
import {StyleSheet, View, Text, Button} from 'react-native';
export default ({navigation}) => {
return (
<View style={styles.container}>
<Text style={styles.text}>세번째 페이지입니다.</Text>
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡreset
<Button
onPress={() => navigation.reset({routes: [{name: 'last'}]})}
title="다음 페이지로"
color="#999"
/>
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
</View>
);
};
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import React from "react";
import { Text, TouchableOpacity, View } from "react-native";
import Movies from "../screen/Movies";
import My from "../screen/My";
const Tab = createBottomTabNavigator();
export default function Tabs() {
return (
<Tab.Navigator
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ sceneContainerStyle 적용 예시 code
sceneContainerStyle={{
backgroundColor: "skyblue",
}}
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ screenOptins={{}} 적용 예시 code.
screenOptions={{
headerRight: () => (
<TouchableOpacity>
<Text style={{ color: "black" }}>햄버거버튼</Text>
</TouchableOpacity>
),
}}>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
<Tab.Screen
options={{
title: "Moive List", // header 이름 설정
tabBarLabel: "Recommend", // Tab 이름 설정
}}
name="Movies Selector"
component={Movies}
/>
<Tab.Screen name="My Page" component={My} />
</Tab.Navigator>
);
}
export default function Tabs() {
return (
<Tab.Navigator
screenOptions={{
tabBarLabelPosition: "beside-icon", // "below-icon" 두 가지가 있음,
}}>
<Tab.Screen
options={{
title: "Moive List",
tabBarLabel: "Recommend",
}}
name="Movies Selector"
component={Movies}
/>
<Tab.Screen name="My Page" component={My} />
</Tab.Navigator>
);
}
사용 예시
<Tab.Screen
options={{
title: "Moive List",
tabBarLabel: "Recommend",
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ options={{}} 속성 중 하나.
tabBarIcon: (color, size) => (
<MaterialIcons name="movie-filter" size={32} color={"red"} />
),
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ tabBarIcon : () => {return } // return은 중괄호와 함께 생략가능.
}}
name="Movies Selector"
component={Movies}
/>
상태이상 알림 뱃지
<Tab.Screen
name="My Page"
component={My}
options={{
tabBarIcon: (color, size) => (
<Feather name="user" size={32} color={"red"} />
),
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ tabBarBedge
tabBarBadge: "3", // 상태이상 알림 뱃지
}}
/>
import React from "react";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { Text, TouchableOpacity, View } from "react-native";
import Stacks from "./Stacks";
import Tabs from "./Tabs";
const Stack = createNativeStackNavigator();
export default function Root() {
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ여기 코드 !
return (
<Stack.Navigator screenOptions={{ headerShown: false }}> {/*Tabs의 헤더를 감춰줌*/}
<Stack.Screen name="Tabs" component={Tabs} />
<Stack.Screen name="Stacks" component={Stacks} />
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡComponent Stack의 Screen Component인 Tabs / Stacks를 Root Component로 한 번에 불러옴.
</Stack.Navigator>
);
}
import React from "react";
import { Text, TouchableOpacity, View } from "react-native";
export default function Movies({ navigation: { navigate } }) {
return (
<View>
<Text>Movies</Text>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ여기 코드 !
<TouchableOpacity onPress={() => navigate("Stacks", { screen: "one" })}>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡStacks 컴포넌트의 one screen 컴포넌트 화면으로 간다 !
<Text>Go To One Screen</Text>
</TouchableOpacity>
</View>
);
}
<TouchableOpacity onPress={() => navigate("Stacks", { screen: "one" })}>
코드 요약 : navigate("보여줄 screen component가 있는 component", {"보여줄 screen component : name 속성 기입."})
import React from "react";
import { Text, TouchableOpacity, View } from "react-native";
export default function Movies({ navigation: { navigate } }) {
return (
<View>
<Text>Movies</Text>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ여기 코드 !
<TouchableOpacity
onPress={() =>
navigate("Stacks", { screen: "one", params: { id: "ONESCREEN" } })
}>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 버튼 클릭 시, one screen component에 id값을 담아 보낸다 !
<Text>Go To One Screen</Text>
</TouchableOpacity>
</View>
);
}
// 여기 코드 !
const One = ({ route: { params }, navigation: { navigate } }) => {
// 인자로 {route : {params} } 해주면 보내준 params를 받을 수 있다 !
console.log("====================================");
console.log(params); // 제대로 받았나 확인..
console.log("====================================");
return (
<TouchableOpacity
onPress={() => {
return navigate("two");
}}>
<Text>One</Text>
</TouchableOpacity>
);
};
// useFocusEffect는 useCallback이라는 메소드가 또 들어간다.
useFocusEffect(
useCallback( () => {
console.log("Focus");
return () => {
console.log("Blur")
};
}, [] )
)
const Three = ({ navigation: { goBack, reset } }) => {
return (
<View>
<TouchableOpacity onPress={() => goBack()}>
<Text>Three</Text>
</TouchableOpacity>
//ㅡㅡㅡㅡㅡㅡㅡㅡreset 여기 !
<TouchableOpacity
onPress={() => reset({ index: 0, routes: [{ name: "one" }] })}>
//ㅡㅡㅡㅡㅡㅡㅡㅡreset 여기 !
{/*reset은 navigation history 자체를 싹 다 밀어버림.
예시 : history가 남아있는 경우, one -> two로 화면 이동했다는 가정하에, two에서 다시 one으로 갈 수 있지만, 싹 다 밀어버렸기 때문에 two에서 뒤로가기 버튼이 없어짐.*/}
<Text>Reset Navigation</Text>
</TouchableOpacity>
</View>
);
};
app.json에서 "expo"의 value값 중에 "userInterfaceStyle": "automatic", 이렇게 바꿔줘야 한다. default값은 light로 되어있음.
emulator에서 darkMode 확인 : shift + cmd + a
예제코드
import { useColorScheme } from "react-native";
import {
DarkTheme,
DefaultTheme,
NavigationContainer,
} from "@react-navigation/native";
import Root from "./navigation/Root";
export default function App() {
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡuseColorScheme() 메서드 활용.
const isDark = useColorScheme() === "dark";
console.log("isDark : ", isDark);
return (
<NavigationContainer theme={isDark ? DarkTheme : DefaultTheme}>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡisDark가 true이면 다크모드, 아니면 일반 모드
<Root />
</NavigationContainer>
);