[React Native]React Navigation을 알아보자

lovjgb·2022년 12월 15일
  • 공식 문서를 참고하여.. 만든 정리본 입니다 :) 제 기준으로 정리를 해두다보니 내용이 빠져있을 수 있습니다.

네비게이션

npm install @react-navigation/native @react-navigation/native-stack

기본 앱
npm install react-native-screens react-native-safe-area-context

기본 스택

createNativeStackNavigator

  • Screen및 Navigator 을 반환하는 함수이다.
  • 탐색트리를 관리하고 탐색 상태를 포함하는 구성요소이다.
  • 모든 네비게이터 구조를 래핑해야 한다.

Stack.Navigator

  • 콘텐츠를 렌더링 하는 구성 요소이다.
  • initialRouteName 를 통해 기본 페이지를 설정할 수 있다.
  • 이를 통해 각각의 스크린컴포넌트에 navigation을 넘겨준다. 해당 컴포넌트에서는 {navigation}을 props로 받아 함수를 사용할 수 있다. navigation.navigate

Stack.Screen

  • name 은 대문자로 하는것이 일반적이다 name="Home"

  • name, component가 기본으로 들어가야 한다. component={HomeScreen}

  • 화면별 옵션을 지정할 때에는 options={{ title: 'Overview' }} 를 통해 전달이 가능하다. (상단에 페이지 제목으로 들어가는 문자열이 된다)

  • Stack.Screen 으로 화면을 정의할 수 있다.

  • onPress ⇒ navigation.navigate('Profile') 로 페이지 전환 가능하다.

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

const MyStack = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{ title: 'Welcome' }}
        />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

화면 이동

const HomeScreen = ({ navigation }) => {
  return (
    <Button
      title="Go to Jane's profile"
      onPress={() =>
        navigation.navigate('Profile', { name: 'Jane' })
      }
    />
  );
};
const ProfileScreen = ({ navigation, route }) => {
  return <Text>This is {route.params.name}'s profile</Text>;
};
  • 다음 페이지로 이동
  • Home으로 가는 경우 popToTop과 같은 효과
  • 호출할 때 마다 push탐색 스택에 새 경로를 추가한다.
  • Page1→Page2→Page1 로 계속해서 push해서 가는 경우 기존의 Page1에 있던 입력값은 사라진다.
  • goBack() 을 통해 이전에 했던 페이지로 갈 수 있고, 그 이전 페이지에 입력했던 입력값이 그대로 있을 것이나, 이 경우 원하는 페이지 이동이 안될 가능성이 있다.
  • 이전 페이지로 이동
  • 맨 처음 스택으로 돌아간다. 결국 첫 페이지에서 goback()을 할 경우 앱이 꺼지게 될 것이다.

Param 매개변수 전달

  • 기본적으로 param을 전달해주는 방법
navigation.navigate('Details', {
            itemId: 86,
            otherParam: 'anything you want here',
          });

초기 params를 가진 page를 만들 수 있다

<Stack.Screen
  name="Details"
  component={DetailsScreen}
  initialParams={{ itemId: 42 }}
/>

입력한 값을 이전 페이지에 전달 할 수 있다


//Page2
navigation.navigate({
            name: 'Home',
            params: { post: postText },
            merge: true,
          });

//입력값을 post:postText에 담아서 이전 페이지로 전달한다.

//Home 에서 사용한다
React.useEffect(() => {
    if (route.params?.post) {
      // Post updated, do something with `route.params.post`
      // For example, send the post to the server
    }
  }, [route.params?.post]);
<Text style={{ margin: 10 }}>Post: {route.params?.post}</Text>

중첩 페이지에서의 매개변수 이전

function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Messages" component={Messages} /> // --->Home안에 다른 페이지 중첩
    </Tab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={Home}
          options={{ headerShown: false, animationEnabled:false
											//상단바 안보이게, 에니메이션 효과 false
}}
        />
        <Stack.Screen name="Profile" component={Profile} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

이때에는 매개변수를 다르게 전달한다

navigation.navigate('Account', {
  screen: 'Settings',
  params: { user: 'jane' },
});
  • 중첩 페이지 내에서 뒤로 버튼을 누르면 중첩 스택 내의 이전 화면으로 돌아간다. 부모의 스택 이전화면이 아님!

주의점

  • 매개변수로 데이터를 넘겨주고 싶을 때 전체 데이터를 넘겨주고 싶겠지만 그렇게 하면 버그가 발생할 수 있다. 가장 필요한 Id만 넘겨주어 사용하는 것이 바람직하다.
  • 최소한으로 전달한다.

요약

  • navigate push 탐색 중인 경로에 매개 변수를 전달할 수 있도록 선택적 두 번째 인수를 수락합니다 . 예: navigation.navigate('RouteName', { paramName: 'value' })
  • route.params화면 내부 를 통해 매개변수를 읽을 수 있습니다 .
  • 다음을 사용하여 화면의 매개변수를 업데이트할 수 있습니다.navigation.setParams
  • initialParamsScreen 초기 매개변수는 소품을 통해 전달할 수 있습니다 .
  • 매개변수는 화면을 표시하는 데 필요한 최소한의 데이터를 포함해야 합니다.
  • options ={}
  • options에는 여러가지 옵션이 있다.
  • 커스텀을 해서 내보낼 수도 있다.
    • options={{ headerTitle: (props) => <LogoTitle {...props} /> }}
function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{
          title: 'My home', // 타이틀
          headerStyle: {
            backgroundColor: '#f4511e', // 해더 배경색
          },
          headerTintColor: '#fff', // 해더 폰트컬러
          headerTitleStyle: { 
            fontWeight: 'bold', // 폰트의 스타일 지정
          },
        }}
      />
    </Stack.Navigator>
  );
}
  • 버튼 넣기
function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{
          headerTitle: (props) => <LogoTitle {...props} />, //커스텀 타이틀
          headerRight: () => ( // 버튼 추가!
            <Button
              onPress={() => alert('This is a button!')}
              title="Info"
              color="#fff"
            />
          ),
        }}
      />
    </Stack.Navigator>
  );
}

Tab, Drawer

  • Drawer
    • 왼쪽에 서랍 처럼 나오며, 페이지 전환이 가능하다.
    • 스택 네비게이터가 안에 중첩되어 있는 경우 drawer의 메서드를 사용할 수 있다. 하지만 상위에 있는 경우에는 사용 불가.
  • Tab
    • 아래에 바 처럼 나타난다. , 페이지 전환이 가능하다.
  • 특징
    • 각각의 화면에 전달된 params는 해당 route에만 사용 가능하다. 엑세스불가.
    • goback을 하는 경우 중첩 내의 첫번째 화면에 있는 경우 상위 네비게이터로 돌아간다.
  • useFocusEffect
    • 해당 화면에 초점이 맞춰져 있는 경우 콜백함수를 넣어 사용한다.

      import { useFocusEffect } from '@react-navigation/native';
      
      function Profile() {
        useFocusEffect(
          React.useCallback(() => {
            // Do something when the screen is focused
      
            return () => {
              // Do something when the screen is unfocused
              // Useful for cleanup functions
            };
          }, [])
        );
      
        return <ProfileContent />;
      }
  • 중첩은 많은 단점이 있다.. 최소화하는 것이 좋다.
    • 깊게 중첩된 뷰 계층 구조를 초래, 메모리 성능문제, 혼란스로운 UX,등등
    • Stack.Group을 통해 그룹화할 수 있다.
function Root() {
  return (
    <Drawer.Navigator>
      <Drawer.Screen name="Home" component={Home} />
      <Drawer.Screen name="Profile" component={Profile} />
      <Stack.Screen name="Settings" component={Settings} />
// drawer 안에 stack이 중첩되어 있는 경우 stack의 헤더 위에 drawer이 나타난다.
    </Drawer.Navigator>
  );
}

function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen
			  name="Chat"
			  component={Chat}
			  listeners={({ navigation, route }) => ({
			    tabPress: (e) => {
			      // Prevent default action
			      e.preventDefault();

			      // Do something with the `navigation` object
			      navigation.navigate('AnotherPlace');
						//클릭 시 해당 페이지로 이동가능, 아래에 있던 탭이 사라지게 가능하다.
			    },
			  })}
			/>
    </Tab.Navigator>
  );
}

접근성

  • 시각장애인 분들을 위한 표시
  • accessible ={true} false를 통해 액세스 및 VoiceOver가 문자열을 읽도록 허용한다.
<TouchableOpacity
  accessible={true}
  accessibilityLabel="Tap me!"
  onPress={onPress}>
  <View style={styles.button}>
    <Text style={styles.buttonText}>Press me!</Text>
  </View>
</TouchableOpacity>

accessibilityLabelledBy

  • [안드로이드] 를 연결시킴으로써 초점을 맞춰준다.
    • Text - nativeID === TextInput - accessibilityLabelledBy 일치시키기

accessibilityHint

  • [iOS] - VoiceOver 설정에서 힌트를 활성화한 경우 VoiceOver는 레이블 뒤의 힌트를 읽어준다.
  • [안드로이드] - 힌트는 무조건 읽어준다.
    • Button - accessibilityHint === 힌트 내용을 적는다

이외에도 많은 것들이 있다.. https://reactnative.dev/docs/accessibility

profile
lovjgb

0개의 댓글