반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- MAC
- localserver
- 티스토리챌린지
- Chrome
- centos
- 오블완
- IOS
- qunit
- xcode
- build
- 리눅스
- unittest
- ReactNative
- vsCode
- node
- 맥
- PYTHON
- jest
- react
- 네트워크
- linux
- MachineLearning
- androidstudio
- VirtualBox
- 센토스
- webpack
- 개발
- TensorFlow
- Android
Archives
- Today
- Total
로메오의 블로그
[React Native] Stack navigation 사용하기 (2022년 기준) 본문
반응형
App.tsx
import React from 'react';
import {
SafeAreaView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<View>
<Text>Restaurant App</Text>
<View style={styles.content}>
<Text>Explore</Text>
<Text>Restaurant</Text>
<Text>Profile</Text>
</View>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
content: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 150,
},
});
export default App;
파일 추가
$ mkdir screen
$ mkdir components
$ touch screen/Explore.tsx
$ touch screen/Restaurants.tsx
$ touch screen/Profile.tsx
$ touch components/RestaurantCard.tsx
$ touch components/Menu.tsx
RestaurantCard.tsx
import {View, Text, StyleSheet} from 'react-native';
import React from 'react';
interface Props {
name: string;
}
const RestaurantCard: React.FC<Props> = ({name}) => {
return (
<View style={styles.container}>
<Text>{name}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#efefef',
padding: 16,
marginTop: 8,
},
});
export default RestaurantCard;
Menu.tsx
import {View, Text, StyleSheet, TouchableOpacity} from 'react-native';
import React from 'react';
const Menu = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Navigation</Text>
<TouchableOpacity
onPress={() => {
// Explore
}}>
<Text style={styles.link}>Explore</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
// Restaurant
}}>
<Text style={styles.link}>Restaurant</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
// Profile
}}>
<Text style={styles.link}>Profile</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#efefef',
padding: 16,
marginTop: 8,
},
title: {
fontSize: 18,
},
link: {
fontSize: 16,
marginTop: 4,
color: '#097ade',
fontWeight: 'bold',
},
});
export default Menu;
Explore.tsx
import {View, Text, StyleSheet} from 'react-native';
import React from 'react';
import RestaurantCard from '../components/RestaurantCard';
const ExploreScreen = () => {
return (
<View style={styles.container}>
<Text style={styles.screenTitle}>식당 목록</Text>
<View>
<Text style={styles.sectionTitle}>근처식당</Text>
<RestaurantCard name="일식" />
<RestaurantCard name="중식" />
<RestaurantCard name="한식" />
<Text style={styles.sectionTitle}>인기식당</Text>
<RestaurantCard name="양식" />
<RestaurantCard name="분식" />
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
marginTop: 24,
},
restaurantCard: {
backgroundColor: '#efefef',
},
screenTitle: {
fontSize: 26,
marginTop: 8,
fontWeight: 'bold',
},
sectionTitle: {
fontSize: 20,
marginTop: 16,
},
});
export default ExploreScreen;
Restaurants.tsx
import {View, Text, StyleSheet, ScrollView} from 'react-native';
import React from 'react';
import RestaurantCard from '../components/RestaurantCard';
import Menu from '../components/Menu';
const RestaurantsScreen = () => {
return (
<View style={styles.container}>
<Text style={styles.screenTitle}>식당</Text>
<ScrollView>
<RestaurantCard name="일식" />
<RestaurantCard name="중식" />
<RestaurantCard name="한식" />
<RestaurantCard name="양식" />
<RestaurantCard name="분식" />
</ScrollView>
<Menu />
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
marginTop: 24,
},
screenTitle: {
fontSize: 26,
marginTop: 8,
fontWeight: 'bold',
},
});
export default RestaurantsScreen;
Profile.tsx
import {View, Text, StyleSheet, TouchableOpacity} from 'react-native';
import React from 'react';
const ProfileScreen = () => {
return (
<View style={styles.container}>
<Text style={styles.screenTitle}>Profile</Text>
<Text>name: 홍길동</Text>
<TouchableOpacity>
<Text>편집</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
marginTop: 24,
},
screenTitle: {
fontSize: 26,
marginTop: 8,
fontWeight: 'bold',
},
});
export default ProfileScreen;
react-native navigation 설치
$ npm install @react-navigation/native --save
$ npm install react-native-screens react-native-safe-area-context --save
$ npm install @react-navigation/native-stack --save
iOS 모듈 설치
$ cd ios
$ pod install
$ cd ..
Android 모듈 설치
...
import android.os.Bundle;
public class MainActivity extends ReactActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}
...
}
App.tsx 수정
import React from 'react';
import ExploreScreen from './screen/Explore';
import ProfileScreen from './screen/Profile';
import RestaurantsScreen from './screen/Restaurants';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
const RootStack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<RootStack.Navigator initialRouteName="Explore">
<RootStack.Screen name="Explore" component={ExploreScreen} />
<RootStack.Screen name="Restaurants" component={RestaurantsScreen} />
<RootStack.Screen name="Profile" component={ProfileScreen} />
</RootStack.Navigator>
</NavigationContainer>
);
};
export default App;
Stack Navigation
App.tsx
import React from 'react';
import ExploreScreen from './screen/Explore';
import ProfileScreen from './screen/Profile';
import RestaurantsScreen from './screen/Restaurants';
import RestaurantScreen from './screen/Restaurant';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
export type RootStackParams = {
Explore: any;
Restaurants: any;
Profile: any;
Restaurant: {
name: string;
};
};
const RootStack = createNativeStackNavigator<RootStackParams>();
const App = () => {
return (
<NavigationContainer>
<RootStack.Navigator initialRouteName="Explore">
<RootStack.Screen name="Explore" component={ExploreScreen} />
<RootStack.Screen name="Restaurants" component={RestaurantsScreen} />
<RootStack.Screen name="Profile" component={ProfileScreen} />
<RootStack.Screen name="Restaurant" component={RestaurantScreen} />
</RootStack.Navigator>
</NavigationContainer>
);
};
export default App;
Explore.tsx
import {View, Text, StyleSheet} from 'react-native';
import React from 'react';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
import RestaurantCard from '../components/RestaurantCard';
import Menu from '../components/Menu';
import {RootStackParams} from '../App';
type Props = NativeStackScreenProps<RootStackParams, 'Explore'>;
const ExploreScreen = ({navigation}: Props) => {
return (
<View style={styles.container}>
<Text style={styles.screenTitle}>식당 목록</Text>
<View>
<Text style={styles.sectionTitle}>근처식당</Text>
<RestaurantCard
name="일식"
onPress={() => {
navigation.navigate('Explore');
}}
/>
<RestaurantCard
name="중식"
onPress={() => {
navigation.navigate('Explore');
}}
/>
<RestaurantCard
name="한식"
onPress={() => {
navigation.navigate('Explore');
}}
/>
<Text style={styles.sectionTitle}>인기식당</Text>
<RestaurantCard
name="양식"
onPress={() => {
navigation.navigate('Explore');
}}
/>
<RestaurantCard
name="분식"
onPress={() => {
navigation.navigate('Explore');
}}
/>
</View>
<Menu />
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
marginTop: 24,
},
restaurantCard: {
backgroundColor: '#efefef',
},
screenTitle: {
fontSize: 26,
marginTop: 8,
fontWeight: 'bold',
},
sectionTitle: {
fontSize: 20,
marginTop: 16,
},
});
export default ExploreScreen;
Profile.tsx
import {View, Text, StyleSheet, TouchableOpacity} from 'react-native';
import React from 'react';
const ProfileScreen = () => {
return (
<View style={styles.container}>
<Text style={styles.screenTitle}>Profile</Text>
<Text>name: 홍길동</Text>
<TouchableOpacity>
<Text>편집</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
marginTop: 24,
},
screenTitle: {
fontSize: 26,
marginTop: 8,
fontWeight: 'bold',
},
});
export default ProfileScreen;
Restaurants.tsx
import {View, Text, StyleSheet, ScrollView} from 'react-native';
import React from 'react';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
import RestaurantCard from '../components/RestaurantCard';
import Menu from '../components/Menu';
import {RootStackParams} from '../App';
type Props = NativeStackScreenProps<RootStackParams, 'Restaurant'>;
const RestaurantsScreen = ({navigation}: Props) => {
return (
<View style={styles.container}>
<Text style={styles.screenTitle}>식당</Text>
<ScrollView>
<RestaurantCard
name="일식"
onPress={name => {
navigation.navigate('Restaurant', {name});
}}
/>
<RestaurantCard
name="중식"
onPress={name => {
navigation.navigate('Restaurant', {name});
}}
/>
<RestaurantCard
name="한식"
onPress={name => {
navigation.navigate('Restaurant', {name});
}}
/>
<RestaurantCard
name="양식"
onPress={name => {
navigation.navigate('Restaurant', {name});
}}
/>
<RestaurantCard
name="분식"
onPress={name => {
navigation.navigate('Restaurant', {name});
}}
/>
</ScrollView>
<Menu />
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
marginTop: 24,
},
screenTitle: {
fontSize: 26,
marginTop: 8,
fontWeight: 'bold',
},
});
export default RestaurantsScreen;
Restaurant.tsx
import {View, Text, StyleSheet} from 'react-native';
import React from 'react';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
import RestaurantCard from '../components/RestaurantCard';
import {RootStackParams} from '../App';
type Props = NativeStackScreenProps<RootStackParams, 'Restaurant'>;
const RestaurantScreen = ({route, navigation}: Props) => {
return (
<View style={styles.container}>
<Text style={styles.screenTitle}>{route.params.name}</Text>
<Text>Relate Restaurant</Text>
<RestaurantCard
name="Sushi 1"
onPress={() => {
navigation.navigate('Restaurant', {name: 'Sushi 1'});
}}
/>
<RestaurantCard
name="Sushi 2"
onPress={() => {
navigation.navigate('Restaurant', {name: 'Sushi 2'});
}}
/>
<RestaurantCard
name="Sushi 3"
onPress={() => {
navigation.navigate('Restaurant', {name: 'Sushi 3'});
}}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
marginTop: 24,
},
screenTitle: {
fontSize: 26,
marginTop: 8,
fontWeight: 'bold',
},
});
export default RestaurantScreen;
RestaurantCard.tsx
import {View, Text, StyleSheet, TouchableOpacity} from 'react-native';
import React from 'react';
interface Props {
name: string;
onPress: (name: string) => void;
}
const RestaurantCard: React.FC<Props> = ({name, onPress}) => {
return (
<TouchableOpacity onPress={() => onPress(name)}>
<View style={styles.container}>
<Text>{name}</Text>
</View>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#efefef',
padding: 16,
marginTop: 8,
},
});
export default RestaurantCard;
Menu.tsx
import {View, Text, StyleSheet, TouchableOpacity} from 'react-native';
import React from 'react';
import {useNavigation} from '@react-navigation/native';
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
import {RootStackParams} from '../App';
const Menu = () => {
const navigation =
useNavigation<NativeStackNavigationProp<RootStackParams>>();
return (
<View style={styles.container}>
<Text style={styles.title}>Navigation</Text>
<TouchableOpacity
onPress={() => {
navigation.navigate('Explore');
}}>
<Text style={styles.link}>Explore</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
navigation.navigate('Restaurants');
}}>
<Text style={styles.link}>Restaurant</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
navigation.navigate('Profile');
}}>
<Text style={styles.link}>Profile</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#efefef',
padding: 16,
marginTop: 8,
},
title: {
fontSize: 18,
},
link: {
fontSize: 16,
marginTop: 4,
color: '#097ade',
fontWeight: 'bold',
},
});
export default Menu;
반응형
'Frontend > React' 카테고리의 다른 글
[React Native] Tab navigation 사용하기 (2022년 기준) (0) | 2022.10.12 |
---|---|
[React Native] Stack navigation 사용하기 2 (2022년 기준) (0) | 2022.10.12 |
[React Native] 프로젝트 생성하기 (2022년 기준) (0) | 2022.10.10 |
[React.js] Firebase Realtime 데이터베이스 불러오기 (0) | 2019.07.14 |
[React.js] Router 적용하기 [Multiple Router] (0) | 2019.07.14 |
Comments