RactNavigation
- 리액트 네비게이션에서 지원하는 네비게이션의 종류는 스택(stack) 네비게이션, 탭(tab) 네비게이션, 드로어(drawer) 네비게이션 세 종류이다. 이 포스트에서는 리액트 네비게이션5 버전을 기준으로 진행할 것이다.
- 종류
- NavigationContainer 컴포넌트
- 네비게이션의 계층구조와 상태를 관리하는 컨테이너 역할을 하며, 모든 네비게이션 구성 요소를 감싼 최상위 컴포넌트이다.
- Navigator 컴포넌트
- 화면을 관리하는 중간 관리자 역할로 네비게이션을 구성하며, 여러 개의 Screen 컴포넌트를 자식 컴포넌트로 가진다.
- Screen 컴포넌트
- Screen 컴포넌트는 화면으로 사용되는 컴포넌트로 name과 component 속성을 지정해야 한다.
DarkMode
- NavigationContainer theme props
- "userInterfaceStyle": "automatic" 로 변경
- NavigationContainer에 theme props를 적용한다.
- 리액트 네이티브에서 제공하는 useColorScheme 훅을 사용하여 다크모드인지 아닌지 판별한다.
- theme props를 다크모드라면 리액트 네이티브에서 제공하는 Theme인 DarkTheme 아니라면 DefaultTheme로 설정한다.
- ThemeProvider
- emotion 라이브러리에서 제공해주는 ThemeProvider 컴포넌트를 제일 외각에 씌워주면 theme을 제공해줄 수 있다.
- 앞으로 styledComponents를 사용할 때 props.theme 으로 어디서든 자유롭게 접근할 수 있다.
연습 코드
import {
DarkTheme,
DefaultTheme,
NavigationContainer,
} from "@react-navigation/native";
import Root from "./navigation/Root";
import { useColorScheme } from "react-native";
import { ThemeProvider } from "@emotion/react";
import { darkTheme, lightTheme } from "./theme";
export default function App() {
const isDark = useColorScheme() === "dark";
return (
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
<NavigationContainer theme={isDark ? DarkTheme : DefaultTheme}>
<Root />
</NavigationContainer>
</ThemeProvider>
);
}
import { Text, TouchableOpacity } from "react-native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
const Stack = createNativeStackNavigator();
const One = ({ route: { params }, navigation: { navigate } }) => {
console.log(params);
return (
<TouchableOpacity onPress={() => navigate("two")}>
<Text>One</Text>
</TouchableOpacity>
);
};
const Two = ({ navigation: { navigate, setOptions } }) => {
return (
<>
<TouchableOpacity onPress={() => navigate("three")}>
<Text>Two</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() =>
setOptions({
title: "변경된 제목!",
})
}
>
<Text>Set Options</Text>
</TouchableOpacity>
</>
);
};
const Three = ({ navigation: { goBack, reset } }) => {
return (
<>
<TouchableOpacity onPress={() => goBack()}>
<Text>Three</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() =>
reset({
index: 1,
routes: [{ name: "three" }, { name: "one" }, { name: "two" }],
})
}
>
<Text>Reset Navigation</Text>
</TouchableOpacity>
</>
);
};
export default function StackNav() {
return (
<Stack.Navigator
initialRouteName="three"
screenOptions={{
headerTintColor: "red",
}}
>
{}
{}
<Stack.Screen name="one" component={One} />
<Stack.Screen name="two" component={Two} />
<Stack.Screen
options={{
presentation: "modal",
}}
name="three"
component={Three}
/>
</Stack.Navigator>
);
}
import React from "react";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import Movies from "../screen/MyMovies";
import My from "../screen/My";
import { MaterialIcons } from "@expo/vector-icons";
import { Foundation } from "@expo/vector-icons";
import { useColorScheme } from "react-native";
import { DARK_COLOR } from "../colors";
const Tab = createBottomTabNavigator();
export default function BottomTabNav() {
const isDark = useColorScheme === "dark";
return (
<Tab.Navigator
screenOptions={{
tabBarLabelPosition: "beside-icon",
}}
sceneContainerStyle={{ backgroundColor: isDark ? DARK_COLOR : "white" }}
>
{}
{}
<Tab.Screen
options={{
title: "영화",
headerTitleAlign: "center",
tabBarLabel: "Movies",
tabBarIcon: ({ color, size }) => (
<MaterialIcons name="local-movies" size={size} color={color} />
),
}}
name="Movies"
component={Movies}
/>
<Tab.Screen
options={{
title: "내가 작성한 댓글",
tabBarLabel: "My",
tabBarIcon: ({ color, size }) => (
<Foundation name="social-myspace" size={size} color={color} />
),
}}
name="My"
component={My}
/>
</Tab.Navigator>
);
}
import React from "react";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { Text, TouchableOpacity } from "react-native";
import StackNav from "./StackNav";
import BottomTabNav from "./BottomTabNav";
const Stack = createNativeStackNavigator();
export default function Root() {
return (
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="BottomTabNav" component={BottomTabNav} />
<Stack.Screen name="StackNav" component={StackNav} />
</Stack.Navigator>
);
}
import { GREEN_COLOR, YELLOW_COLOR } from "./colors";
export const lightTheme = {
title: GREEN_COLOR,
upcomingText: "black",
};
export const darkTheme = {
title: YELLOW_COLOR,
upcomingText: "white",
};