얼렁뚱땅
[React Native] Stack Navigation 사용하기 본문
Stack Navigation 이란?
현재 화면 위에 다른 화면을 쌓으면서 화면을 이동하는 것. push와 pop을 이용하기 때문에 stack이다.
Stack Navigation 라이브러리 설치
npm i @react-navigation/stack
파일, 폴더 구성
screen 폴더
- Mainscreen.js
- Result.js
navigations 폴더
- MainscreenStack.js
- MypageStack.js (추후 생성 예정)
기본 구조는 tab이나 drawer와 비슷하다.
src 밖 App.js -> src/App.js -> navigations/index.js -> MainTab.js -> MainscreenStack.js -> Mainscreen.js, Result.js 페이지 가져오기!
src 밖 App.js
import App from './src/App';
export default App;
모든 코드를 src 폴더 내에서 관리하는 것이 편해서 이렇게 했다.
src/App.js
import React from 'react';
import Navigation from './navigations';
export default function App() {
return <Navigation />;
}
이상하게 <View> component 안에 <Navigation>을 두면 화면이 아무것도 안나타난다. 그래서 일단은 임시로 이렇게 두었다. 나중에 <ThemeProvider>를 사용할 예정. <Navigation> 컴포넌트 가져오기.
navigations/index.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import MainTab from './MainTab';
const Navigation = () => {
return (
<NavigationContainer>
<MainTab />
</NavigationContainer>
);
};
export default Navigation;
반드시 <NavigationContainer>로 감싸주어야 한다. <MainTab> 컴포넌트 가져오기.
navigations/MainTab.js
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import MainscreenStack from './MainscreenStack';
import Mypage from '../screens/Mypage';
import Instagram from '../screens/Instagram';
const Tab = createBottomTabNavigator();
const MainTab = () => {
return (
<Tab.Navigator>
<Tab.Screen name="MainscreenStack" component={MainscreenStack} />
<Tab.Screen name="Mypage" component={Mypage} />
<Tab.Screen name="Instagram" component={Instagram} />
</Tab.Navigator>
);
};
export default MainTab;
3개의 tab으로 구성. 이건 기본 틀만 보여주기 위한 코드이고, tab, drawer navigation이 모두 완성된 코드는 아래 참고.
https://dev-sailor.tistory.com/27
stack navigation 만들기
MainscreenStack.js
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import Mainscreen from '../screens/Mainscreen';
import Result from '../screens/Result';
const Stack = createStackNavigator();
const MainscreenStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Mainscreen" component={Mainscreen} />
<Stack.Screen name="Result" component={Result} />
</Stack.Navigator>
);
};
export default MainscreenStack;
- createStackNavigator 함수를 이용해서 스택 네비게이션 생성
- Navigator 컴포넌트 안에 Screen 컴포넌트를 자식 컴포넌트로 작성
- Screen 컴포넌트 안에 Mainscreen 컴포넌트와 Result 컴포넌트로 지정
Mainscreen이 가장 먼저 나오고 버튼을 누르면 result 페이지로 이동하도록 설정할 것이다.
Mainscreen.js
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
export default function Mainscreen({ navigation }) {
return (
<View style={styles.container}>
<Text style={styles.text}>MainScreen Page</Text>
<Button
title="go to Result page"
onPress={() => navigation.navigate('Result')}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 30,
},
});
Screen 컴포넌트의 component로 지정된 컴포넌트는 화면으로 이용되고 navigation이 props로 전달된다
navigation에는 다양한 기능이 있는데 그중 navigate 함수는 원하는 화면으로 이동하는 데 사용된다.
Mainscreen 화면에서 props로 전달되는 navigation을 사용해서 버튼을 클릭하면 Result 화면으로 이동하도록 만든 것이다. 단, 전달되는 화면의 이름은 screen 컴포넌트의 name 값 중 하나를 입력해야 한다.
기본 틀만 만들면 위와 같은 화면이 나온다. header가 두번 나오는 문제가 있다.
Header 숨기기
사용할 수 있는 설정이 2가지가 있다.
- headerMode
- headerShown
headerMode
Navigator 컴포넌트의 속성으로 헤더를 렌더링하는 방법 설정
- float : 헤더가 상단에 유지되면 하나의 헤더 사용. iOS 동작 방식
- screen : 각 화면마다 헤더를 가지며 화면 변경과 함꼐 나타나거나 사라짐. Andriod 동작 방식
- none : 헤더가 렌더링 되지 않음
hearderShown
화면 옵션
Navigator 컴포넌트의 screenOptions에서 설정하면 전체 화면의 헤더가 보이지 않고
Screen 컴포넌트의 options에서 설정하면 그 화면에서만 헤더가 보이지 않는다.
나는 headerShown : false 를 Mainscreen 페이지에서 사용했다.
MainTab.js
<Tab.Screen
name="Mainscreen"
component={MainscreenStack}
options={{
headerShown: false,
tabBarIcon: (props) =>
TabIcon({
...props,
name: props.focused ? 'home-variant' : 'home-variant-outline',
}),
}}
/>
헤더 중복 문제 해결
Header 가운데 정렬
헤더를 가운데 정렬 시키고 싶다.
headerTitleAlign 속성을 이용한다.
headerTitleAlign에서는 left와 center 두 가지가 값 중 하나만 설정할 수 있다. iOS는 center로, 안드로이드는 left가 기본값으로 설정되어 있다.
MainscreenStack.js
<Stack.Navigator screenOptions={{ headerTitleAlign: 'center' }}>
<Stack.Screen name="Mainscreen" component={Mainscreen} />
<Stack.Screen name="Result" component={Result} />
</Stack.Navigator>
이동하는 화면에 정보 전달하기
navigate 함수를 이용할 때 두 번째 파라미터에 객체를 전달해서 이동하는 화면에 필요한 정보를 함께 전달하는 기능이 있다.
이번에는 Mypage에서 코드를 작성해보고자 한다.
먼저 화면에서 사용할 임시 목록을 만들기
Mypage.js
const items = [
{ id: 1, name: 'first image' },
{ id: 2, name: 'second image' },
{ id: 3, name: 'third image' },
];
그리고 항목 수 만큼 버튼 생성하기
{items.map((item) => (
<Button
key={item.id}
title={item.name}
onPress={() => _onPress(item)}
/>
))}
버튼을 눌렀을 때 해당 항목의 정보와 함께 화면 이동하기
navigate 함수를 이용 시 두번째 파라미터에 객체를 전달
const _onPress = (item) => {
navigation.navigate('Image', { id: item.id, name: item.name });
};
전달된 내용은 컴포넌트의 props로 전달되는 route의 params를 통해 확인 가능
Image.js
export default function Image({ route }) {
return (
<View style={styles.container}>
<Text style={styles.text}>Image Page</Text>
<Text>ID: {route.params.id}</Text>
<Text>Name: {route.params.name}</Text>
</View>
);
}
'React Native' 카테고리의 다른 글
[React Native] 스타일링 속성들(2) (0) | 2021.08.21 |
---|---|
[React Native] 스타일링 적용 방법(1) (0) | 2021.08.21 |
[React Native] Drawer Navigation (tab navigation과 동시에 사용하기) (0) | 2021.08.13 |
[React Native] Tab Navigation 사용하기 (0) | 2021.08.12 |
[React Native] Expo 프로젝트 만들기 (0) | 2021.08.09 |