FrontEnd :-)

[RN] study 6week / 리액트 내비게이션 ① 본문

React Native

[RN] study 6week / 리액트 내비게이션 ①

code10 2023. 3. 17. 23:45

React Navtive 스터디 6week

도서: [리액트 네이티브를 다루는 기술 / 김민준 / 길벗]

(5장 리액트 내비게이션으로 여러 화면 관리하기 ①)

 

5.1 설치 및 적용하기

5.2 기본적인 사용법

5.3 다양한 내비게이터

5.4 내비게이션 Hooks

5.5 정리


여러 화면으로 구성된 애플리케이션을 만들려면 내비게이션 관련 서드 파티 라이브러리를 사용해야 한다.

내비게이션과 관련해 사용할 수 있는 라이브러리 2가지

1) react-navigation : 리액트 네이티브 커뮤니티에서 관리. 사용률이 가장 높음. 리액트 공식 메뉴얼에서도 이 라이브러리로 화면을 전환하는 방법을 소개. 내비게이션 기능이 자바스크립트로 구현되어 있음. 사용법도 2)보다 쉽고, 별도 API가 아닌 리액트 컴포넌트를 사용해 화면을 설정할 수 있다는 장점이 있음.

2) react-native-navigation : 홈페이지 제작 서비스 Wix에서 관리. 이미 만들어진 네이티브 앱에 리액트 네이티브를 적용하는 경우 사용하기에 더 적합. 내비게이션 기능이 자바스크립트가 아닌 각 플랫폼의 네이티브 코드로 구현되어 있기 때문에 react-navigation보다 더욱 네이티브스러운 사용 경험을 제공.


5.1 react-navigation 설치 및 적용하기

yarn add @react-navigation/native

//react-navigation이 의존하는 라이브러리도 설치
yarn add react-native-screens react-native-safe-area-context

//ios디렉터리에서 Pod 설치도 잊지 말기
cd ios
pod install

>> 설치 후 다시 상위 폴더로 와서 스타투
cd ../
yarn start

5.1.2 라이브러리 적용

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

NavigationContainer 컴포넌트를 불러와서 앱 전체를 감싸주어야 함.


5.2 기본적인 사용법

5.2.1 네이티브 스택 내비게이터

native-stack navigation은 가장 흔히 사용되며, 안드로이드에서는 Fragment, iOS에서는 UINavigationController를 사용해 일반 네이티브 앱과 정확히 동일한 방식으로 화면을 관리합니다. 

yarn add @react-navigation/native-stack

screens/HomeScreen.tsx

screens/DetailScreen.tsx

화면 전용 컴포넌트들 만들고, App 에서 네이티브 스택 내비게이터 사용

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/DetailScrren';

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;

<Stack.Screen name="Home" component={HomeScreen} />에서 name은 화면의 이름을 설정하는 Props. 반드시 대문자로 시작할 필요는 없으나, 권장사항임)

 

5.2.2 스크린 이동하기

//screens/HomeScreen.tsx

(...)
  <Button
    title="Detail 열기"
    onPress={() => navigation.navigate('Detail')}
  />
(...)

onPress 설정해주면 이동~

새 화면이 나타날 때 기본적으로, iOS는 우측에서 좌측으로, 안드로이드는 아래에서 위로 보임. 스크린 전환 효과는 바꿀 수 있음.

기본 생김새도 다른데, 커스터마이징 가능함.

navigate 대신 push 함수도 가능!

  <Button
    title="Detail 열기"
    onPress={() => navigation.push('Detail')}
  />

5.2.3 라우트 파라미터

새로운 화면을 보여줄 때 의존해야 하는 어떤 값이 있으면 라우트 파라미터(객체 타입으로) 설정!

     <Button
        title="Detail 1 열기"
        onPress={() => navigation.navigate('Detail', {id: 1})}
      />

navigate VS push

- navigate는 push와 달리 새로 이동할 화면이 현재 화면과 같으면 새로운 화면을 쌓지 않고 파라미터만 변경. push는 화면 전환되어서 뒤로 가기하면 이전 화면이지만, navigate는 뒤로 가기하면 Home 화면이 됨.

- navigate 함수는 지금 사용하고 있는 네이티브 스택 내비게이터 외에 다른 내비게이터에도 있지만, push 함수는 네이티브 스택 내비게이터에서만 사용 가능!

 

5.2.4 뒤로가기

뒤로 가기 :  navigation.pop(),

가장 첫 번째 화면으로 이동 : navigation.popToTop()

 

5.2.5 헤더 커스터마이징하기

1. options 설정

//App.tsx

<Stack.Screen
  name="Home"
  component={HomeScreen}
  options={{
   title: '홈',
  }}
/>

2. navigation.setOptions

//HomeScrren.tsx

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

=> 둘 다 설정해 놓으면 navigation.setOptions 설정값이 나옴.

 

Detail 화면 타이틀 텍스트 바꾸기

1. options 설정

//App.tsx 
//id type이 정해지지 않아서 타입스크립트는 오류남 => 수정 필요
//?연산자도 타입스크립트 오류때문에 넣음
        <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={({route}) => ({
            title: `상세 정보 - ${route?.params?.id}`,
          })}
        />

2. navigation.setOptions

//DetailScreen.tsx

useEffect(() => {
    navigation.setOptions({
      title: `상세 정보 - ${route.params.id}`,
    });
  }, [navigation, route.params.id]);

5.2.5.2 헤더 스타일 변경하기

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

5.2.5.3 헤더의 좌측, 타이틀, 우측 영역에 다른 컴포넌트 보여주기

const options = {
  headerBackVisible: false, //안드로이드에서 화살표 아이콘 없애기
  headerLeft: ({onPress}: any) => (
    <TouchableOpacity onPress={onPress}>
      <Text>Left</Text>
    </TouchableOpacity>
  ),
  headerTitle: ({children}: any) => (
    <View>
      <Text>{children}</Text>
    </View>
  ),
  headerRight: () => (
    <View>
      <Text>Right</Text>
    </View>
  ),
};

=> 타입스크립트 적절한 적용이 필요한데... 우선 any로 설정..

=> 안드로이드 화면의 경우, 화살표가 나타나는데, 화살표를 없애려면 headerBackVisible: false 설정이 필요하다.

 

5.2.5.4 헤더 숨기기

//screens/HeaderlessScreen.tsx

import React from 'react';
import {Button, Text, View} from 'react-native';
import type {NativeStackScreenProps} from '@react-navigation/native-stack';
import {SafeAreaView} from 'react-native-safe-area-context';

type RootStackParamList = {
  Headerless: undefined;
};

type Props = NativeStackScreenProps<RootStackParamList, 'Headerless'>;

function HeaderlessScreen({navigation}: Props) {
  return (
    <SafeAreaView>
      <View>
        <Text>Header 없음</Text>
        <Button onPress={() => navigation.pop()} title="뒤로가기" />
      </View>
    </SafeAreaView>
  );
}

export default HeaderlessScreen;

=> HeaderlessScreen 파일 만들고, App에서 Stack.Screen 설정하고, HomeScreen에 버튼으로 화면 열어보게 설정~

=> 아이폰에서 StatusBar 영역을 침범하지 않으려면, SafeAreaView 설정이 필요 . react-native 또는 react-native-safe-area-context 에서 불러올 수 있다.

=> 모든 페이지에서 헤더 없애려면, Stack.Navigator에 screenOptions={{headerShown: false}} 설정하면 됨.

Comments