study: 리네다기 | 5장 - React Navigation

Lumpen·2023년 4월 13일
0

Study

목록 보기
55/92

react native 에서 사용할 수 있는 네비게이션 라이브러리는 두 가지가 있다

react-navigation : 리액트 네이티브 커뮤니티에서 관리하는 사용률이 가장 높은 라이브러리, 공식 문서에서도 소개하고 있다
reat-native-navigation: 홈페이지 제작 서비스 Wix 에서 관리한다 이미 만들어진 네이티브 앱에 사용하는 편이 좋다 조금 더 네이티브 스러운 사용 경험

App.js

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';

const App() {
	return <NavigationContainer>{/* 내비 설정 */}</NavigationContainer>
}

export default App

NavigationContainer 컴포넌트로 사용할 앱 전체를 감싸주어야 한다

웹 브라우저에는 History 기능은 Stack 자료구조를 사용해 구현되어 있다

React Navigation 을 네이티브로 사용할 때는 사용성을 제공하기 위해
Native Stack Navigator 를 사용한다

Native Stack Navigator

Native Stack Navigator 는 가장 흔히 사용되고
안드로이드에서는 Fragment 를 iOS 에서는 UINavigationController 를
사용해 일반 네이티브 앱과 정확히 동일한 방식으로 화면을 관리합니다.

네이티브 스택 내비게이터를 사용하기 위해서는 라이브러리를 추가로 설치해주어야 한다
npm install @react-navigation/native-stack

App.js

import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from './screens/HomeScreen';
import DetailScreen from './screens/DetailScreen';

const Stack = createNativeStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Detail" component={DetailScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

createNativeStackNavigator 함수를 사용하면 Stack 객체가 생성된다
객체 안의 Navigator 와 Screen 컴포넌트를 사용해 화면을 설정할 수 있다
이 컴포넌트의 name 은 화면의 이름을 설정하는 Props
화면 이름은 공식 문서에서 대문자로 시작하는 것을 권장한다

Navigator 로 Screen 을 감싸 사용

navigation.navigate('Detail') 를 사용해 화면 이동
push 함수를 사용해도 화면 전환할 수 있다

push 함수를 사용하면 같은 화면도 계속 네비게이션 스택에 쌓인다
navigate 는 push 와 달리 새로 이동할 화면이 현재 화면과 같으면 새로운 화면을 쌓지 않고 파라미터만 변경한다

뒤로가기를 할 때는 pop, 가장 첫 번째 화면으로 가려면 popToTop 메서드 사용

헤더 커스터마이징

react-navigation 에서는 타이틀 영역을 header 라고 부른다

타이틀 텍스트 변경

  1. Stack.Screen Props 를 변경

App.js

 <Stack.Navigator initialRouteName="Home">
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{
            title: '홈',
          }}
        />
        <Stack.Screen name="Detail" component={DetailScreen} />
      </Stack.Navigator>
  1. navigation.setOptions 함수를 사용하여 변경

HomeScreen.js

import React, {useEffect} from 'react';
import {View, Button} from 'react-native';

function HomeScreen({navigation}) {
  useEffect(() => {
    navigation.setOptions({title: '홈'});
  }, [navigation]);
  return (...);
}

export default HomeScreen;

detail 페이지에는 라우터 파라미터로 받아온 route 의 id 를 값을 포함하도록할 때
Screen 에서 Props 설정 시 options 에는 객체를 반환하는 함수를 넣어준다
함수는 route 와 navigation 을 파라미터로 받아올 수 있다

     <Stack.Navigator initialRouteName="Home">
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{
            title: '홈',
          }}
        />
        <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={({route}) => ({
            title: `상세 정보 - ${route.params.id}`,
          })}
        />
      </Stack.Navigator>

헤더 스타일 변경

헤더 스타일 변경 시 Screen 컴포넌트의 headerStyle, headerTintColor, headerTitleStyle
등의 속성을 사용할 수 있다

 <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{
            title: '홈',
            // Header 블록에 대한 스타일
            headerStyle: {
              backgroundColor: '#29b6f6',
            },
            // Header의 텍스트, 버튼들 색상
            headerTintColor: '#ffffff',
            // 타이틀 텍스트의 스타일
            headerTitleStyle: {
              fontWeight: 'bold',
              fontSize: 20,
            },
          }}
        />

헤더 좌/우측, 타이틀 영역 컴포넌트

opstions 에 headerLeft, headerTitle, headerRight 를 갖는 객체를 반환한다
각 키들은 값으로 컴포넌트를 리턴하는 함수를 가진다

 <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={{
            headerLeft: ({onPress}) => (
              <TouchableOpacity onPress={onPress}>
                <Text>Left</Text>
              </TouchableOpacity>
            ),
            headerTitle: ({children}) => (
              <View>
                <Text>{children}</Text>
              </View>
            ),
            headerRight: () => (
              <View>
                <Text>Right</Text>
              </View>
            ),
          }}
        />

안드로이드는 좌측에 화살표 아이콘이 나타난다는데
headerBackVisible 옵션을 false 로 지정하면 된다

<Stack.Screen
  name="Detail"
  component={DetailScreen}
  options={{
    headerBackVisible: false,
    headerLeft: ({onPress}) => (

헤더 안보이게 설정

Navigator 의 screenOptions 에 headerShown: false 를 주면 된다

screenOptions={{
    headerShown: false,
  }}

드로어 네비게이터

드로어 내비게이터는 좌/우측에 사이드 바를 만들 때 사용
사이드 바를 모바일에서는 드로어라고 부른다

drawerContent 에 SafeAreaView 를 꼭 사용한다
그렇지 않으면 드로어 상단 영역이 StatusBar 영역과 겹친다

하단 탭 내비게이터

하단 탭 네비게이터는 전체 영역에 대해 swipe 를 막는 옵션이 없던 것 같은데
상단 탭 내비게이터의 옵션을 bottom 으로 주어 사용하는 편이 좋지 않을까 싶기도..
아마 내가 사용해봤던게 머터리얼 하단 탭이라 그럴지도 모르겠다

tabBarKeyboardHidesTabBar 옵션을 통해 키보드 생성 시 하단 탭을 가린다는데
어떨지 모르겠다 사용해보고 너무 차이나게 좋으면 하단 탭으로 변경을 고려해보는 편도..

• Stack.Navigator
- Main (Tab.Navigator)
• Home
• Search
• Notification
• Message
- Detail

stack 내비게이터 안에 탭 네비게이터 를 사용할 수 있다

머터리얼 상단 탭

머터리얼 하단 탭 네비게이터는 하단에만 나타나고
활성화된 탭에 따라 전체 탭의 배경색을 변경할 수 있다
탭이 활성화되면 해당 탭이 살짝 올라온다

상단 탭은 상단, 하단 모두 가능

내비게이션 Hooks

네비게이션에 관련된 Hooks 도 있다

navigation 이나 route 객체를 사용중이 아닌 컴포넌트에서 사용하도록
하는 방법은 3가지가 있다

  1. 넘겨야할 파라미터가 들어있는 함수를 Props 로 전달하는 방법

function OpenDetailButton({onPress}) {
  return <Button title="Detail 1 열기" onPress={onPress} />;
}

function HomeScreen({navigation}) {
  return (
    <View>
      <Text>Home</Text>
      <OpenDetailButton onPress={() => navigation.push('Detail', {id: 1})} />
    </View>
  );
}
  1. Props 로 navigation 객체를 넘겨주는 방법
function OpenDetailButton({navigation}) {
  return (
    <Button
      title="Detail 1 열기"
      onPress={() => navigation.push('Detail', {id: 1})}
    />
  );
}

function HomeScreen({navigation}) {
  return (
    <View>
      <Text>Home</Text>
        <OpenDetailButton navigation={navigation} />
    </View>
  );
}
  1. Hooks 사용

useNavigation 훅을 호출하면 navigation 객체를 반환한다
const navigation = useNavigation();

useRoute 훅을 호출하면 route 객체를 반환한다

const route = useRoute();

useFocusEffect는 꼭 useCallback과 같이 사용한다
useCallback을 사용하지 않으면 컴포넌트가 리렌더링될 때마다 useFocusEffect에 등록한함수가 호출된다

useCallback은 컴포넌트 내부에서 함수를 만들 때
매번 새로 만든 함수를 사용하지 않고 이전에 만든 함수를 다시 사용한다
함수 내부의 로직에서 의존하는 값이 있다면 의존하는 값이 바뀌었을 때 함수를 교체한다

profile
떠돌이 생활을 하는. 실업자는 아니지만, 부랑 생활을 하는

0개의 댓글