[리액트 네이티브를 다루는 기술 #8] 5장 리액트 내비게이션으로 여러...

[리액트 네이티브를 다루는 기술 #8] 5장 리액트 내비게이션으로 여러...

@ List

* 5.3 다양한 내비게이터

** 5.3.1 드로어 내비게이터 --> drawer 모듈 에러로 Pass

** 5.3.2 하단 탭 내비게이터

@ Note

1. Drawer 라이브러리 에러

- 라이브러리 설치 시 에러 (해결 완료)

> reference : https://bocoder.tistory.com/66?category=904878

ios / android - Drawer Module Install Error in Android

- const Drawer = createDrawerNavigator(); 설정 시 에러 (해결 필요)

> reference : https://github.com/software-mansion/react-native-reanimated/issues/1849

ios / android - createDrawerNavigator Error

2. 종류별 Tabs Navigator 의 Props

- 하단 탭 내비게이터 : https://reactnavigation.org/docs/bottom-tab-navigator/

- 머티리얼 상단 탭 내비게이터 : https://reactnavigation.org/docs/material-top-tab-navigator/

- 머티리얼 하단 탭 내비게이터 : https://reactnavigation.org/docs/material-bottom-tab-navigator/

- 머티리얼 디자인 관련 : https://callstack.github.io/react-native-p/

3. 내비게이션 Hooks

- useNavigation : Screen으로 사용되고 있지 않은 컴포넌트에서도 navigation 객체 사용 가능

- useRoute : Screen으로 사용되고 있지 않은 컴포넌트에서도 route 객체 사용 가능

- useFocusEffect : 화면에 포커스가 작협을 떄 특정 작업을 할 수 있게 하는 Hook

> useFocusEffect는 반드시 useCallback과 함께 사용해야 함

> 사용하지 않으면 컴포넌트가 리렌더링 될 때마다 useFocusEffect에 등록한 함수가 호출됨

@ Git

- https://github.com/eunbok-bocoder/LearnReactNavigation.git

# Source tree

# App.js ( 하단 탭 내비게이터 )

import React from 'react'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import MainScreen from './screens/MainScreen'; import DetailScreen from './screens/DetailScreen'; const Stack = createNativeStackNavigator(); function App() { return ( ); } export default App;

# screens/MainScreen.js ( 하단 탭 내비게이터 )

import React from 'react'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import {Text, Button, View} from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; const Tab = createBottomTabNavigator(); function HomeScreen({navigation}) { return ( Home { navigation.push('Detail', {id: 1}); }} /> ); } function SearchScreen() { return ( Search ); } function NotificationScreen() { return ( Notification ); } function MessageScreen() { return ( Message ); } function MainScreen() { return ( ( ), }} /> ( ), }} /> ( ), }} /> ( ), }} /> ); } export default MainScreen;

# screens/DetailScreen.js ( 하단 탭 내비게이터 )

import React, {useEffect} from 'react'; import {View, Text, StyleSheet, Button} from 'react-native'; function DetailScreen({route, navigation}) { useEffect(() => { navigation.setOptions({ title: `상세 정보 - ${route.params.id}`, }); }, [navigation, route.params.id]); return ( id: {route.params.id} navigation.navigate('Detail', {id: route.params.id + 1})} onPress={() => navigation.push('Detail', {id: route.params.id + 1})} /> navigation.pop()} /> navigation.popToTop()} /> ); } export default DetailScreen; const styles = StyleSheet.create({ block: { flex: 1, alignItems: 'center', justifyContent: 'center', }, text: { fontSize: 48, }, buttons: { flexDirection: 'row', }, });

이전 이전 01234 ios / android - 하단 탭 내비게이터 설정

# App.js ( 머티리얼 상단 탭 내비게이터 )

import React from 'react'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import MainScreen from './screens/MainScreen'; import DetailScreen from './screens/DetailScreen'; const Stack = createNativeStackNavigator(); function App() { return ( ); } export default App;

# screens > MainScreen.js ( 머티리얼 상단 탭 내비게이터 )

import React from 'react'; // import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs'; import {Text, Button, View} from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; // 하단 탭 내비게이터 // const Tab = createBottomTabNavigator(); // 머티리얼 상단 탭 내비게이터 const Tab = createMaterialTopTabNavigator(); function HomeScreen({navigation}) { return ( Home { navigation.push('Detail', {id: 1}); }} /> ); } function SearchScreen() { return ( Search ); } function NotificationScreen() { return ( Notification ); } function MessageScreen() { return ( Message ); } function MainScreen() { return ( ( ), }} /> ( ), }} /> ( ), }} /> ( ), }} /> ); } export default MainScreen;

이전 이전 01 ios / android - 머티리얼 상단 탭 내비게이터 설정

# App.js ( 머티리얼 하단 탭 내비게이터 )

import React from 'react'; import { getFocusedRouteNameFromRoute, NavigationContainer, } from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import MainScreen from './screens/MainScreen'; import DetailScreen from './screens/DetailScreen'; const Stack = createNativeStackNavigator(); function getHeaderTitle(route) { const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home'; const nameMap = { Home: '홈', Search: '검색', Notification: '알림', Message: '메시지', }; return nameMap[routeName]; } function App() { return ( ({ title: getHeaderTitle(route), })} /> ); } export default App;

# screens > MainScreen.js ( 머티리얼 하단 탭 내비게이터 )

import React from 'react'; // import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; // import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs'; import {createMaterialBottomTabNavigator} from '@react-navigation/material-bottom-tabs'; import {Text, Button, View} from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; // 하단 탭 내비게이터 // const Tab = createBottomTabNavigator(); // 머티리얼 상단 탭 내비게이터 // const Tab = createMaterialTopTabNavigator(); const Tab = createMaterialBottomTabNavigator(); function HomeScreen({navigation}) { return ( Home { navigation.push('Detail', {id: 1}); }} /> ); } function SearchScreen() { return ( Search ); } function NotificationScreen() { return ( Notification ); } function MessageScreen() { return ( Message ); } function MainScreen() { return ( , tabBarColor: 'black', tabBarBadge: 'new', }} /> ( ), tabBarColor: 'gray', }} /> ( ), tabBarColor: 'green', tabBarBadge: 30, }} /> ( ), tabBarColor: 'blue', tabBarBadge: true, }} /> ); } export default MainScreen;

이전 이전 012345 ios / android - 머티리얼 하단 탭 내비게이터 설정

# screens > MainScreen.js (내비게이션 Hooks 테스트)

import React, {useEffect, useCallback} from 'react'; // import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; // import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs'; import {createMaterialBottomTabNavigator} from '@react-navigation/material-bottom-tabs'; import {Text, Button, View} from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; import {useNavigation, useFocusEffect} from '@react-navigation/native'; // 하단 탭 내비게이터 // const Tab = createBottomTabNavigator(); // 머티리얼 상단 탭 내비게이터 // const Tab = createMaterialTopTabNavigator(); const Tab = createMaterialBottomTabNavigator(); // case 1) // function OpenDetailButton({onPress}) { // return ; // } // case 2) // function OpenDetailButton({navigation}) { // return ( // { // navigation.push('Detail', {id: 1}); // }} // /> // ); // } // case 3) function OpenDetailButton() { const navigation = useNavigation(); return ( { navigation.push('Detail', {id: 1}); }} /> ); } function HomeScreen({navigation}) { // useEffect(() => { // console.log('mounted'); // return () => { // console.log('unmounted'); // }; // }, []); useFocusEffect( useCallback(() => { console.log('이 화면을 보고 있어요.'); return () => { console.log('다른 화면으로 넘어갔어요.'); }; }, []), ); return ( Home {/* { navigation.push('Detail', {id: 1}); }} /> */} {/* navigation.push('Detail', {id: 1})} /> */} {/* */} ); } function SearchScreen() { return ( Search ); } function NotificationScreen() { return ( Notification ); } function MessageScreen() { return ( Message ); } function MainScreen() { return ( , tabBarColor: 'black', tabBarBadge: 'new', }} /> ( ), tabBarColor: 'gray', }} /> ( ), tabBarColor: 'green', tabBarBadge: 30, }} /> ( ), tabBarColor: 'blue', tabBarBadge: true, }} /> ); } export default MainScreen;

# screens > DetailScreen.js (내비게이션 Hooks 테스트)

import React, {useEffect} from 'react'; import {View, Text, StyleSheet, Button} from 'react-native'; import {useRoute} from '@react-navigation/native'; function IDText() { const route = useRoute(); return id: {route.params.id}; } function DetailScreen({route, navigation}) { useEffect(() => { navigation.setOptions({ title: `상세 정보 - ${route.params.id}`, }); }, [navigation, route.params.id]); return ( {/* id: {route.params.id} */} navigation.navigate('Detail', {id: route.params.id + 1})} onPress={() => navigation.push('Detail', {id: route.params.id + 1})} /> navigation.pop()} /> navigation.popToTop()} /> ); } export default DetailScreen; const styles = StyleSheet.create({ block: { flex: 1, alignItems: 'center', justifyContent: 'center', }, text: { fontSize: 48, }, buttons: { flexDirection: 'row', }, });

반응형

from http://bocoder.tistory.com/67 by ccl(A) rewrite - 2021-12-30 21:01:07