음파를 리뉴얼하는 과정에서 하단 네비게이션을 수정해야 했는데,
기존에는 옛날 버전을 이용했기에 이번 기회에 react-navigation v6을 이용해서 수정했어요.
우선 react-navigation을 설치합니다.
npm install @react-navigation/native
그런데 v6 버전의 네비게이터는 추가로 다른 dependencies들을 필요로 하는 모양이에요. 역시 설치해줍시다.
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context
웹 브라우저의 경우는 a 태그를 통해서 링크를 달아 페이지 전환이 이루어진답니다.
태그를 클릭할 경우, url을 history stack에 push하게 되고
뒤로 가기를 누를 시, 이전의 url을 pop 하는 형태에요.
react-native의 경우 이 history를 global하게 관리하는 장치가 없다고 해요. 그래서 여러개의 stack이 존재하고 각각의 stack은 웹 브라우저 처럼 작동을 해요.
다만 차이점이라면, react-native의 경우 제스처나 애니메이션등의 효과를 추가적으로 제공할 수 있다는 점 !
npm install @react-navigation/native-stack
참고로 이 라이브러리는 위에서 설치한 react-native-screens에 의존한다고 해요!
createNativeStackNavigator는 Navigator와 Screen을 프로퍼티로 갖는 객체를 리턴하게 되고 이 두가지는 react component에요.
const stack = createNativeStackNavigator();
<stack.Navigator>
<stack.Screen name="Example" component={Example}/>
</stack.Navigator>
결국 루트를 구성하기 위해서는 위와 같이 Navigator와 Screen을 이용해야 하는데 Screen을 자식으로 포함해야 한답니다.
props
(Navigator)
(Screen)
import React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Home = () => {
return (
<View>
<Text>Home Screen</Text>
</View>
)
}
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home}/>
</Stack.Navigator>
</NavigationContainer>
)
}
자 이제는 앱에서 제일 많이 이용되는 하단 네비게이션을 만들기 위한 방법을 알아보겠습니다,,
npm install @react-navigation/bottom-tabs
stack navigator의 createNativeStackNavigator와 유사한 방식이에요.
createBottomTabNavigator를 이용해서 Navitor와 Screen을 프로퍼티로 갖는 객체를 생성해서 이용합니다,,
import React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const First = () => {
return (
<View>
<Text>This is first screen</Text>
</View>
)
}
const Second = () => {
return (
<View>
<Text>This is second screen</Text>
</View>
)
}
const Tab = createBottomTabNavigator()
const App = () => {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="first" component={First}/>
<Tab.Screen name="second" component={Second}/>
</Tab.Navigator>
</NavigationContainer>
)
}
위처럼 두개의 하단 네비게이션을 간단하게 만들 수 있습니다.
자, 이제 화면을 스택으로 묶어줬다면 이동할 수 있어야 해요.
바로 navigation props을 이용하는 것인데요. 바로 확인해봅시다,,
const Home = ({ navigation }) => {
return (
<View>
<Button
title="go to Details Screen"
onPress={() => navigation.navigate('Details')}
/>
</View>
)
}
위처럼 navigation에 있는 navigate 함수를 이용해서 이동하게 됩니다!
동일한 화면으로 navigate하게 되면 어떻게 될까요?
정답은 ... 이동하지 않는다! 입니다.
음파를 개발할 때도 이것 때문에 애를 먹었던,,
왜냐하면 Stack에 해당 routes가 있는지 확인하고 있다면 작동하지 않기 때문이에요.
.......그렇다면 어떻게?
<Button
title="go to Details Screen"
onPress={() => navigation.push('Details')}
/>
위처럼 push를 이용하게 된다면 stack에 기존의 route가 있던 없던 상관 없이 계속해서 Detalis components를 넣어주기 때문에 새로운 화면으로 이동할 수 있어요.
<Button
title="go to previous screen"
onPress={() => navigation.goBack()}
/>
위처럼 goBack을 이용하면 이전 화면으로 되돌아갈 수 있답니다.
<Button
title="go to previous screen"
onPress={() => navigation.popToTop()}
/>
특히나, depth가 깊어짐에 따라 초기화면으로 바로 돌아가고 싶다면 popToTop을 이용하거나 navigate(initialRouteName)을 이용한답니다.
A화면에서 B화면으로 params를 전달할 수 있습니다.
navigation.navigate(routeNames, { ...params})의 형태로 전달하게 되고, 받는 쪽에서는 route.params를 통해 받게 됩니다.
const AScreen = ({ navigation }) => {
return (
<Button
title="go to B Screen"
onPress={() => navigation.navigate("BScreen", {
name: 'BIBI',
content: 'B Screen is here',
})
/>
)
}
const BScreen = ({ route }) => {
const { name, content } = route.params;
// print BIBI, B Screen is here
console.log(name, content);
return null;
}