2020. 12. 25. 01:44ㆍReact/React Native
1. 사전 작업
새로운 프로젝트 생성
2. Navigation
React Native는 지속적으로 개발되어 가고 있기 때문에, 버전별 사용법이 다를 수 있다. 그렇기 때문에 공식 문서(reactnavigation.org/docs/getting-started)를 확인하여 제작하는 것을 권장한다.
설치된 목록은 package.json 파일에서 확인할 수 있다.
// Navigation 설치
npm install @react-navigation/native
// 의존성 설치
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
npx pod-install
3. Stack Navigator
1) Stack Navigator 설치
npm install @react-navigation/stack
2) Linking
React Navigation은 모든 컴포넌트를 NavigationContainer로 감싸주어야 하며, Stack Navigator를 사용하기 위해 createStackNavigator 메서드를 이용해야한다. NavigationContainer는 Navigation의 구조와 상태를 관리하기 위한 컴포넌트이며 createStackNavigator 메서드는 Screen이랑 Navigator라는 두개의 속성을 반환하는 함수이다.
순차적으로 진행하기 위해서 다음의 항목을 처리해준다.
- src 폴더 하위에 home.js, user.js 생성
- App.js에 home.js, user.js import
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './src/home';
import UserScreen from './src/user';
const Stack = createStackNavigator();
class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name='Home' component={HomeScreen}/>
<Stack.Screen name='User' component={UserScreen}/>
</Stack.Navigator>
</NavigationContainer>
)
}
}
const styles = StyleSheet.create({
});
export default App;
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
class HomeScreen extends Component {
render() {
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>Home Screen</Text>
<Button
title='To User Screen'
onPress={()=>{
this.props.navigation.navigate('User')
}}
/>
</View>
)
}
}
const styles = StyleSheet.create({
});
export default HomeScreen;
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
class UserScreen extends Component {
render() {
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>User Screen</Text>
<Button
title='To Home Screen'
onPress={()=>{
this.props.navigation.navigate('Home')
}}
/>
</View>
)
}
}
const styles = StyleSheet.create({
});
export default UserScreen;
3) Navigation Params
데이터 전달을 설명하기 앞서, Stack.Navigator의 initialRouteName속성을 이용하여 화면을 지정하게 되면 지정한 화면이 첫 화면으로 출력이 되는 것을 확인할 수 있다.
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
class HomeScreen extends Component {
render() {
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>Home Screen</Text>
<Button
title='To User Screen'
onPress={()=>{
this.props.navigation.navigate('User', { // UserScreen으로 전달하는 값
userIdx: 100,
userName: 'Gildong',
userLastName: 'Hong'
})
}}
/>
</View>
)
}
}
const styles = StyleSheet.create({
});
export default HomeScreen;
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
class UserScreen extends Component {
render() {
const {params} = this.props.route; // params 객체는 이 스크린의 route 값을 할당해준다.
const userIdx = params ? params.userIdx : null;
const userName = params ? params.userName : null;
const userLastName = params ? params.userLastName : null;
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>User Screen</Text>
<Button
title='To Home Screen'
onPress={()=>{
this.props.navigation.navigate('Home')
}}
/>
<Text>User idx: {JSON.stringify(userIdx)}</Text>
<Text>User userName: {JSON.stringify(userName)}</Text>
<Text>User userLastName: {JSON.stringify(userLastName)}</Text>
</View>
)
}
}
const styles = StyleSheet.create({
});
export default UserScreen;
Stack Screen 생성 시에 route 파라미터 값을 초기화할 수도 있다.
...
class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='User'>
<Stack.Screen name='Home' component={HomeScreen}/>
<Stack.Screen
name='User'
component={UserScreen}
initialParams={{
userIdx: 50,
userName: 'Gildong',
userLastName: 'Go'
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
}
...
3) Header Bar 설정
Header Bar의 설정은 setOptions 속성으로 설정이 가능(1)하며, 마찬가지로 초기값을 Options의 값으로 설정(2)할 수 있다.
(1)
class HomeScreen extends Component {
render() {
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>Home Screen</Text>
<Button
title='To User Screen'
onPress={()=>{
this.props.navigation.navigate('User', { // UserScreen으로 전달하는 값
userIdx: 100,
userName: 'Gildong',
userLastName: 'Hong'
})
}}
/>
<Button
title='Change the title'
onPress={() =>
this.props.navigation.setOptions({
title: 'Changed',
headerStyle: {
backgroundColor: 'pink'
},
headerTintColor: 'red'
})
}
/>
</View>
)
}
}
(2)
...
class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Home'>
<Stack.Screen
name='Home'
component={HomeScreen}
options={{title: 'Home Screen'}}
/>
<Stack.Screen
name='User'
component={UserScreen}
options={{ // 초기 Header 값 설정
title: 'User Screen',
headerStyle: {
backgroundColor: 'pink'
},
headerTintColor: 'red',
headerTitleStyle: {
fontWeight: 'bold',
color: 'purple'
}
}}
initialParams={{
userIdx: 50,
userName: 'Gildong',
userLastName: 'Go'
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
}
...
하지만 Stack 스크린이 많고 App.js에서 모든 구성을 처리하는게 힘들다면 각 js 파일에서 설정이 가능하다.
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
class UserScreen extends Component {
headerStyle = () => { // Header bar 스타일 함수
this.props.navigation.setOptions({
title: 'Customizing',
headerStyle: {
backgroundColor: 'blue'
},
headerTintColor: 'yellow',
headerTitleStyle: {
fontWeight: 'bold',
color: 'green'
}
})
}
render() {
this.headerStyle(); // Header bar 스타일 함수 호출
const {params} = this.props.route; // params 객체는 이 스크린의 route 값을 할당해준다.
const userIdx = params ? params.userIdx : null;
const userName = params ? params.userName : null;
const userLastName = params ? params.userLastName : null;
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>User Screen</Text>
<Button
title='To Home Screen'
onPress={()=>{
this.props.navigation.navigate('Home')
}}
/>
<Text>User idx: {JSON.stringify(userIdx)}</Text>
<Text>User userName: {JSON.stringify(userName)}</Text>
<Text>User userLastName: {JSON.stringify(userLastName)}</Text>
</View>
)
}
}
const styles = StyleSheet.create({
});
export default UserScreen;
4) Header Bar 공통 적용
모든 스크린에 공통 스타일을 적용하는 방법은 다음과 같다. 하지만 공통적으로 스타일을 적용을 해도, 하위의 Stack.Screen의 option 속성이 우선순위으므로 Stack.Screen의 스타일이 적용이된다.
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './src/home';
import UserScreen from './src/user';
const Stack = createStackNavigator();
class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName='Home'
screenOptions={{ // 공통 스타일 설정
headerStyle: {
backgroundColor: 'green'
},
headerTintColor: 'white',
headerTitleStyle: {
fontWeight: 'bold',
color: 'pink'
}
}}
>
<Stack.Screen
name='Home'
component={HomeScreen}
options={{title: 'Home Screen'}}
/>
<Stack.Screen
name='User'
component={UserScreen}
initialParams={{
userIdx: 50,
userName: 'Gildong',
userLastName: 'Go'
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
}
const styles = StyleSheet.create({
});
export default App;
5) Header Bar 아이콘 적용
Header Bar에 이미지를 넣고 싶을 경우에는, 배경이 없는 이미지를 다운받고(www.iconfinder.com/search/?q=home) Image 컴포넌트를 이용하여 삽입해주면 된다.
- src 하위에 logo.js 파일 생성
- App.js에 logo.js import
import React, { Component } from 'react';
import { Image } from 'react-native';
import Logo from './assets/pics/homeicon.png';
class LogoTitle extends Component {
render() {
return (
<Image
style={{width: 40, height: 40}}
source={Logo}
/>
)
}
}
export default LogoTitle;
...
import LogoTitle from './src/logo';
const Stack = createStackNavigator();
class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName='Home'
>
<Stack.Screen
name='Home'
component={HomeScreen}
options={{
title: 'Home Screen',
headerTitle: <LogoTitle/> // 로고 이미지 설정 클래스 삽입
}}
/>
<Stack.Screen
name='User'
component={UserScreen}
initialParams={{
userIdx: 50,
userName: 'Gildong',
userLastName: 'Go'
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
}
const styles = StyleSheet.create({
});
export default App;
6) Header Bar 버튼 적용
App.js에 정의(1)하거나 별도로 생성된 js 파일에 정의(2)하여 사용할 수 있다.
(1)
...
<Stack.Screen
name='Home'
component={HomeScreen}
options={{
title: 'Home Screen',
headerTitle: <LogoTitle/>,
headerRight: () => (
<Button
title='Info'
onPress={()=> alert('hello')}
color='orange'
/>
)
}}
/>
...
(2)
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
class UserScreen extends Component {
headerStyle = () => {
this.props.navigation.setOptions({
title: 'Customizing',
headerStyle: {
backgroundColor: 'blue'
},
headerTintColor: 'yellow',
headerTitleStyle: {
fontWeight: 'bold',
color: 'green'
},
headerBackTitle: 'BACK',
headerRight: () => (
<Button
title='Go Back'
onPress={()=> {
this.props.navigation.navigate('Home')
}}
color='orange'
/>
)
})
}
render() {
this.headerStyle();
const {params} = this.props.route; // params 객체는 이 스크린의 route 값을 할당해준다.
const userIdx = params ? params.userIdx : null;
const userName = params ? params.userName : null;
const userLastName = params ? params.userLastName : null;
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>User Screen</Text>
<Button
title='To Home Screen'
onPress={()=>{
this.props.navigation.navigate('Home')
}}
/>
<Text>User idx: {JSON.stringify(userIdx)}</Text>
<Text>User userName: {JSON.stringify(userName)}</Text>
<Text>User userLastName: {JSON.stringify(userLastName)}</Text>
</View>
)
}
}
const styles = StyleSheet.create({
});
export default UserScreen;
'React > React Native' 카테고리의 다른 글
[React Native] Navigation (Tab) (0) | 2020.12.30 |
---|---|
[React Native] Navigation (Drawer) (0) | 2020.12.28 |
[React Native] Image, Modal (0) | 2020.12.25 |
[React Native] Picker, Slider, ActivityIndicator (0) | 2020.12.24 |