리액트 네이티브(React Native)로 인스타그램 UI을 구현하는 포스팅입니다. 인기있는 앱을 따라 만들어 보는 것은 굉장히 재미있습니다.
구글에서 인스타그램 클론 코딩 강의를 찾아보니, 다른 개발자들이 올린 동영상 강의를 몇 개 찾을 수 있었습니다.
- Udemy 강좌: React-Native + Redux + Redux-Saga + INSTAGRAM Clone
- Nomad Coders 강좌: 인스타그램 클론 코딩
사실 위의 강의 2개는 유료입니다. 저처럼 가난한 개발자는 유료 강의도 가끔 듣지만, 무료 강의를 더 많이 이용합니다. 아래는 유튜브에 공개되어 있는 무료 강의입니다. 이 포스팅은 아래 강의를 듣고 정리한 내용입니다.
_
동영상 강의에서는 라이브러리를 먼저 설치하고 프로젝트를 생성하지만, 저는 제 스타일로 프로젝트를 먼저 생성하고 시작합니다.
expo-cli
를 이용하여 프로젝트를 생성합니다.
$ expo-cli init instagram-clone
$ cd instagram-clone
expo-cli
가 없는 분들은 여기를 참고하세요.
그다음, UI 라이브러리를 설치합니다.
$ yarn add native-base @expo/vector-icons
yarn
이 없으신 분들은 여기를 참고하세요.
그 다음은 네비게이션을 위한 라이브러리를 설치합니다.
$ yarn add react-navigation
_
Components 폴더를 생성합니다. 그리고 Components 폴더 아래에 MainScreen.js
를 생성하고 아래와 같이 입력합니다.
import React, { Component } from 'react';
import { StyleSheet, Platform } from 'react-native';
export default class MainScreen extends Component {
render() {
return (
<View style={styles.container}>
<Text>MainScreen</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
_
App.js
파일을 열어서 수정합니다. App.js
파일 상단에 react-navigation
와 방금 만든 ./Components/MainScreen
를 import 합니다. createStackNavigator()
함수를 사용하여 AppStackNavigator
를 생성합니다. 그리고 첫 번째 Navigator에 MainScreen 컴포넌트를 등록합니다.
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import MainScreen from './Components/MainScreen';
const AppStackNavigator = createStackNavigator({
Main:{
screen: MainScreen // MainScreen 컴포넌트를 네비게이터에 등록
}
});
export default createAppContainer(AppStackNavigator);
_
native-base
에서 Icon
을 import하고, navigationOptions
을 생성합니다. navigationOptions
에는 왼쪽에 보여질 ios-camera 아이콘과 오른쪽에 보여질 ios-send 아이콘을 설정합니다.
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Icon } from 'native-base'; // 추가된 코드
export default class MainScreen extends Component {
// navigationOptions 코드 추가
static navigationOptions = {
headerLeft: <Icon name='ios-camera' style={{ paddingLeft:10 }}/>,
title: 'Instagram',
headerRight: <Icon name='ios-send' style={{ paddingRight:10 }}/>,
}
render() {
return (
<View style={styles.container}>
<Text>MainScreen</Text>
</View>
);
}
}
// 이하 코드 생략
_
여기까지 작업한 화면입니다. 상단에 카메라와 비행기 아이콘이 보이나요?
_
Components 폴더 아래에 AppTabNavigator 폴더를 생성합니다. 그리고 AppTabNavigator 폴더 아래에 5개의 파일을 생성합니다. HomeTab.js
, SearchTab.js
, AddMediaTab.js
, LikesTab.js
, ProfileTab.js
파일을 각각 생성합니다. 생성되는 파일의 내용은 아래와 비슷하게 입력합니다.
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default class HomeTab extends Component {
render() {
return (
<View style={style.container}>
<Text>HomeTab</Text>
</View>
);
}
}
const style = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}
});
_
우리가 생성한 파일 구조는 아래와 같습니다.
그 다음은 MainScreen.js
파일을 수정합니다. react-navigation
와 AppTabNavigator 컴포넌트들을 import 합니다. 그리고 하단에 보여줄 탭네비게이터 AppTabNavigator
를 생성합니다.
// ... 일부 import 코드 생략 ...
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
// 하단 탭에 들어갈 컴포넌트들
import HomeTab from './AppTabNavigator/HomeTab'
import SearchTab from './AppTabNavigator/SearchTab'
import AddMediaTab from './AppTabNavigator/AddMediaTab'
import LikesTab from './AppTabNavigator/LikesTab'
import ProfileTab from './AppTabNavigator/ProfileTab'
// 하단 탭 네비게이터 생성
const AppTabNavigator = createBottomTabNavigator({
HomeTab: { screen: HomeTab },
SearchTab: { screen: SearchTab },
AddMediaTab: { screen: AddMediaTab },
LikesTab: { screen: LikesTab },
ProfileTab: { screen: ProfileTab }
});
const AppTabContainet = createAppContainer(AppTabNavigator);
export default class MainScreen extends Component {
// navigationOptions 코드 생략
render() {
return <AppTabContainet/>; // AppTabContainet 컴포넌트를 리턴한다.
}
}
// ... 이하 코드 생략 ...
동영상 강좌에서는
createTabNavigator
를 사용하여 하단 탭 네비게이터를 구현했습니다. 하지만 현재는createTabNavigator
가 deprecated 되었습니다. 그래서createBottomTabNavigator
또는createMaterialTopTabNavigator
를 사용해야합니다.
_
여기까지 작업한 화면입니다.
HomeTab.js
파일을 수정합니다. navigationOptions
를 생성하고, Icon
을 입력합니다.
// ... 일부 import 코드 생략 ...
import { Icon } from 'native-base';
export default class HomeTab extends Component {
static navigationOptions = {
tabBarIcon: ({ tintColor }) => (
<Icon name='ios-home' style={{ color: tintColor }} />
)
}
// ... 이하 코드 생략 ...
이어서 SearchTab.js
, AddMediaTab.js
, LikesTab.js
, ProfileTab.js
파일도 수정합니다. 파일에 아이콘을 각각 'ios-search', 'ios-add-circle', 'ios-heart', 'person'로 입력합니다. 각 파일 내용은 깃허브에 업로드된 파일을 참고하세요.
_
여기까지 작업한 화면입니다.
_
스와이프와 애니매이션을 넣기 위해서는 createMaterialTopTabNavigator
를 사용해야 합니다. 앞에서 createBottomTabNavigator
로 구현했던 네비게이터를 createMaterialTopTabNavigator
로 수정합니다. 그리고 네비게이터에 옵션을 설정합니다. createMaterialTopTabNavigator
옵션에 대한 자세한 설명은 TabNavigatorConfig 문서를 참고하세요.
// ... 일부 import 코드 생략 ...
// createBottomTabNavigator를 createMaterialTopTabNavigator로 수정
import { createMaterialTopTabNavigator, createAppContainer } from 'react-navigation';
const AppTabNavigator = createMaterialTopTabNavigator({
HomeTab:{ screen: HomeTab },
Search:{ screen: SearchTab },
AddMedia:{ screen: AddMediaTab },
Likes:{ screen: LikesTab },
Profile:{ screen: ProfileTab }
}, {
animationEnabled: true,
swipeEnabled: true,
tabBarPosition: "bottom",
tabBarOptions: {
style: {
...Platform.select({
ios:{
backgroundColor:'white',
}
})
},
iconStyle: { height: 100 },
activeTintColor: '#000',
inactiveTintColor: '#d1cece',
upperCaseLabel: false,
showLabel: false,
showIcon: true,
}
});
// ... 이하 코드 생략 ...
_
여기까지 작업한 화면입니다.
이제 하단 탭 아이콘을 클릭하면 페이지 슬라이드 애니메이션이 발생합니다.
_
작업한 코드는 모두 깃허브에 업로드되어 있습니다.
https://github.com/anpigon/rn_instagram_clone
_
여기까지 읽어주셔서 감사합니다.
아니~ 책을 출간하고 방대한 지식을 가지신 분이~ "저처럼 가난한 개발자는 유료 강의도 가끔 듣지만, 무료 강의를 더 많이 이용합니다." 다른 사람의 강의도 보시나요? ㅎㅎ. "리액트를 다루는 기술" 잘 보고 있습니다. 감사합니다. 다음에는 네이티브 실전앱 제작하는 책이 하나 발간되었으면 좋겠습니다. 실제 리액트가 네이티브를 지향하는데 시중에는 실전 ios, 안드로이드 배포까지 만드는 과정이 없더군요. ㅠㅜ.
좋은 글 감사합니다.
아이폰을 기준으로는 버그가 없을 것 같은데 안드로이드에서 버그가 조금 있습니다.
먼저 탭 네비게이터를 생성할 때 bounces 옵션을 안드로이드에서는 넣어줘야 합니다.
옵션에 bounces: true라고 부여하면 됩니다. 또한 위의 코드대로 실행하면 iOS에 대해서만 탭 네비게이터의 색상이 정해진 상태라 파란색 배경으로 나타나는데 ios:{ background: white } 아래에 android: { background: white }라고 해주면 이 부분도 해결됩니다. 또한 글의 첫번째 코드의 클래스명을 App이 아닌 MainScreen입니다. 따라하시는 분들이 헷갈리실거 같아 몇글자 적어봅니다.
👍👍