[React Native] useNavigation와 useRoute 이용해서 화면 이동하고 데이터 전달하기 (Move and Pass data between two screens using Hooks)
안녕하세요 Foma 입니다.
평소에 리액트 네이티브에서 navigation을 props로 전달하는 게 너무 불편했는데요.
오늘은 React-Native에서 navigation을 props로 전달하는 것이 아닌, useNavigation과 useRoute를 만들어 줘서
화면을 이동과 함께 데이터를 전달하고 받아보도록 하겠습니다.
바로 시작할게요~
Install
npm install @react-navigation/native
npm install @react-navigation/native-stack
npm install @react-navigation/stack
npm install react-native-safe-area-context
Navigation
Navigation/index.ts
기존 Props와 같이 Navigation을 구성해 준다.
const Stack = createNativeStackNavigator();
export default function Navigation() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName={screens.Login}>
<Stack.Screen name={screens.Login} component={LoginScreen} />
<Stack.Screen
name={screens.ChatRoom}
component={ChatRoomScreen}
/>
<Stack.Screen name={screens.Chat} component={ChatScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
다만 추가해 줘야 할 부분은 RootStackParamList인데 ,
구성되어 있는 화면에 navigate 될 때 어떤 값들을 넘겨줄 것인지 정의합니다.
export type RootStackParamList = {
LoginScreen: undefined;
ChatRoomScreen: undefined;
ChatScreen: {room: string};
};
ChatRoomScreen.tsx
useNavigation, StackNavigationProp, RootStackParamList를 import 해줍니다.
import {useNavigation} from '@react-navigation/core';
import {StackNavigationProp} from '@react-navigation/stack';
import {RootStackParamList} from '../Navigation';
그 다음 아래와 같이 navigation을 useNaviation으로 만들어 주는데요.
간단하게 설명하면 StackNavigationProp은 Naviation에 있는 Prop들을 정의하는건데, 그것을 위에서 만들어준 RootStackParamList로 하겠다는 의미입니다.
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
챗룸 스크린에서 챗 스크린으로 이동할 때 방 정보를 함께 넘겨주도록 하겠습니다.
위에서 정의해준대로 "ChatScreen" (화면 이름)과 넘겨줄 정보를 입력해 줍니다.
<Pressable
onPress={() => {
navigation.navigate("ChatScreen", {room: 'A'});
}}>
만약 위에서 정의하지 않은 화면 이름이나 prop을 적게 되면 오류가 발생합니다.
ChatScreen.tsx
RouteProp과 useRoute를 import 해줍니다.
import {RouteProp, useRoute} from '@react-navigation/native';
그 다음 아래와 같이 route를 만들어 주는데요.
RouteProp은 RootStackParamList의 "ChatSceen"(param 받아올 화면)으로 구성해 줍니다.
여기서도 위와 마찬가지로 RootStackParamList에 있지 않은 화면을 지정해 주면 오류가 발생합니다.
const route = useRoute<RouteProp<RootStackParamList, "ChatScreen">>();
아래와 같이 type으로 나눠서 지정해 줘도 됩니다.
type ScreenRouteProp = RouteProp<RootStackParamList,"ChatScreen">;
const route = useRoute<ScreenRouteProp>();
그 다음 route의 params에 받아올 정보를 입력하면
console.log(route.params?.room);
아래와 같이 정상적으로 잘 전달되게 됩니다.
느낀 점
React-native로 화면 이동할 때 항상 navigation prop을 넘겨주고 받고 했는데,
이게 화면이 많아지면 많아 질수록 계속해서 네비게이션을 전달해야 했다.
그래서 뭐 상태로 관리할 수 있는 게 없을까 하고 찾아봤더니 useNavigation과 useRoute가 있었다.
확실히 화면 간에 네비게이션을 전달할 게 없어서 더 깔끔해져서 속이 시원했는데,
iOS에서 화면 이동하는 거에 비해 뭐 세팅해줘야 할 게 너무 많아서 엄청 복잡하다는 생각이 들었다..