[강의 기록] 리액트 네이티브 - (2) Navigation

모아나·2025년 2월 18일
0

What is "Navigation?"

  • 네비게이션은 사용자가 화면 간 이동을 가능하게 만드는 기능.
  • 웹에서 URL을 통해 페이지를 탐색하는 것과 유사하나 모바일 앱에서는 버튼을 누르거나 탭을 전환해 화면 간 이동한다.

네비게이션의 역할과 특징

  • 뒤로가기 기능
  • 탭 전환
  • 탭, 스택, 드로어 네비게이션
  • 버튼으로 이동하여 화면 전환
  • URL이 없으며 네비게이션 스택을 기반으로 이동

React Navigation 라이브러리

다양한 네비게이션 패턴을 제공함

  • Stack Navigation: 화면을 스택처럼 쌓아 올리고 뒤로가기를 제공함
  • Tab Navigation: 화면 하단에 탭을 두어 여러 화면 전환 가능
  • Drawer Navigation: 화면 왼쪽 또는 오른쪽에 두어 슬라이드해 열 수 있음
  • 복합: 위 패턴들을 결합해 앱의 구조를 표현. 예를 들어 Stack Navigation 안에 Tab Navigation 포함

Displaying Items in Grid

주요 스타일링

  1. 그림자 효과
  • Android: elevation 속성을 사용.
  • iOS: shadowColor, shadowOpacity, shadowOffset, shadowRadius 조합 사용.
  • 문제: overflow: hidden을 사용하면 iOS에서 그림자가 사라짐.
  • 해결: 플랫폼별로 overflow를 다르게 설정.
    overflow: Platform.OS === 'android' ? 'hidden' : 'visible'
  1. 버튼 눌릴 때 효과
  • Android: android_ripple 속성으로 리플 효과 제공.
  • iOS: Pressable의 style prop에서 pressed 상태를 사용해 opacity 조정.
  styles.button,
  pressed ? styles.buttonPressed : null,
]}

React Navigation Package

리액트 네비게이션

React Navigation Package 설치 후,
앱의 모든 화면을 NavigationContainer로 감싸기

Stack Navigation

  • createNativeStackNavigator: 화면과 사용자 정의 옵션을 포함한 Configuration Object를 인수로 받아 실행되는 함수. 화면은 네비게이터가 표시할 콘텐츠를 렌더링하는 리액트 컴포넌트들.
  • createStaticNavigation: 네비게이터를 인수로 받아 실행되는 함수로 앱에서 렌더링할 수 있는 컴포넌트들을 반환. 앱에서 딱 한번 호출됨
  • navigation은 기본 헤더와 레이아웃을 제공하는데 이는 Stack.NavigatorStack.Screen 에서 커스터마이징 할 수 있다.
import CategoriesScreen from './screens/CategoriesScreen'; // 첫 번째 화면
import MealsOverviewScreen from './screens/MealsOverviewScreen'; // 두 번째 화면

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator
     screenOptions={{
      headerStyle: { backgroundColor: '#f4511e' },
      headerTintColor: '#fff',
      headerTitleStyle: { fontWeight: 'bold' },
  }}
    >
        {/* 첫 번째 화면 */}
        <Stack.Screen
          name="Categories" // 유니크한 화면 이름
          component={CategoriesScreen}
			options={{
      title: 'Meal Categories', // 헤더 제목 변경
    }}// 렌더링할 컴포넌트
        />
        {/* 두 번째 화면 */}
        <Stack.Screen
          name="MealsOverview"
          component={MealsOverviewScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;
  • Stack.Navigator의 가장 첫 번째 스크린이 최초의 스크린이 된다.

Understanding the useNavigation Hook

  • Native 요소와 애니메이션 사용
  • 각 플랫폼에서 OS수준의 성능을 제공
  • 내부적으로 react-native-screens 라이브러리를 활용

Stack Navigator

  • 네이티브 동작을 Javascript 에뮬레이션함
  • 완전한 네이티브 애니메이션은 아니지만, 더 다양한 커스텀이 가능함
  • 화면 전환을 위해 navigation 객체를 사용하는데 이는 props로 전달되며 navigate 메서드를 통해 화면 이동을 처리함

  • 이 객체는 Stack.Screen에 등록된 컴포넌트에서만 기본적으로 접근 가능

import { FlatList } from 'react-native';
import { CATEGORIES } from '../data/dummy-data';
import CategoryGridTile from '../components/CategoryGridTile';

export default function CategoriesScreen({ navigation }) {
  function renderCategoryItem(itemData: any) {
    function pressHandler() {
      navigation.navigate('MealsOverview', {
        categoryId: itemData.item.id,
      });
    }
    return (
      <CategoryGridTile
        title={itemData.item.title}
        color={itemData.item.color}
        onPress={pressHandler}
      />
    );
  }
  return (
    <FlatList
      data={CATEGORIES}
      keyExtractor={(item) => item.id}
      renderItem={renderCategoryItem}
      numColumns={2}
    />
  );
}
  • Screen이 아닌 곳에서 사용하고 싶다면 useNavigation 훅을 사용한다.
import { useNavigation } from '@react-navigation/native';

const CategoryGridTile = () => {
  const navigation = useNavigation();

  return (
    <Pressable onPress={() => navigation.navigate('MealsOverview')}>
      <Text>Go to Meals</Text>
    </Pressable>
  );
};

Working with Route Params To Pass Data Between Screens

https://reactnavigation.org/docs/route-object

  • screen의 경우 {route} props로 받아 데이터를 가져올 수 있다.
  • screen이 아닌 경우, useRoute 훅을 사용해 데이터를 가져올 수 있다.
import { View, Text, StyleSheet } from 'react-native';
import { MEALS } from '../data/dummy-data';

export default function MealsOverviewScreen({ route }) {
  const categoryId = route.params.categoryId;
  // const route= useRoute()
  // route.params 를 대신 사용해도 된다.
  const displayedMeals = MEALS.filter((mealItem) => {
    return mealItem.categoryIds.indexOf(categoryId) >= 0;
  });
  return (
    <View style={styles.container}>
      <Text>Meals Overview Screen a</Text>
      <Text>{categoryId}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
});
profile
Make things

0개의 댓글