본문 바로가기
코딩생활/ReactNative

[React Native] 3-1 다이어리 앱 만들기

by InfoJun 2023. 3. 10.
반응형

앞서 복습하는 겸 작성하는 글들이 있었지만 

 

이젠 그냥 공부하면서 진행하는 것을 올리는게 더 좋을 거 같아 갑자기 뛰어 넘어왔다.


배운걸 종합하여 다이어리 앱을 만드러 볼건데 다룰 내용은 다음과 같습니다.

  • 네비게이션 설정
  • Context API를 사용한 전역 상태 관리
  • date-fns를 사용한 날짜 포맷팅
  • Animated를 사용한 애니메이션 효과

우선 프로젝트를 새로 만들어 줍니다

 

$ npx react-native init DayLog

 

그리고 마찬 가지로 App.tsx파일이 만들어졌기 대문에 .js파일로 리팩토링해줍니다.

 

그후 폴더에 들어가 필요한 라이브러리들을 다운 받겠습니다.

cd DayLog
yarn add @react-navigation/native @react-navigation/native-stack @react-navigation/bottom-tabs react-native-screens react-native-safe-area-context react-native-vector-icons

 

당연히 pod install을 하는 것도 해주어야 합니다.


그 다음은 react-native-vector-icons의 MaterialIcons를 사용하기 위해 파일들을 수정하겠습니다

 

ios/DayLog/info.plist

	<key>UIAppFonts</key>
	<array>
	    <string>MaterialIcons.ttf</string>
	</array>

 

다음 코드를 제일 하단에 추가해 줍니다.

 

android/app/build.gradle

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
project.ext.vectoricons = [
        iconFontName : ['MaterialIcons.ttf']
]
apply from : "../../node_modules/react-native-vector-icons/fonts.gradle"

 

위 코드도 제일 하단에 추가해 줍니다.

 

그 후 App.js로 돌아가 react-navigation을 적용하겠습니다.

 

내용을 다 지운뒤 수정해줍니다.

 

import React from 'react';
import {NavigationContainer} from "@react-navigation/native";

function App(){
    return(
        <NavigationContainer></NavigationContainer>
    )
}



export default App

 

그 후 프로젝트의 화면을 구성해 보겠습니다.

 

다음과 같이 설계하고 두 종류의 네비게이션을 사용할 것입니다.

 

RootStack은 네이티브 스택 네비게이션이고, MainTab은 하단 탭 네비게이션입니다.

 

FeedScreen은 작성한 글을 목록 형태로 보여줄 것이고,

 

CalendarScreen은 달력 혀태로 글을 조회하는 화면입니다.

 

SearchScreen은 글을 검색할 수 있는 화면입니다.

 

WhiteScreen은 글을 작성하거 수정하는 화면인데, MainTab에 넣지않고,

 

RootStack에 넣어 화면이 나타날 때는 하단 탭이 나타나지 않도록 설정하였습니다.

 

그럼 이제 screens 디렉터리를 생성한 뒤 안에 화면들을 준비해주겠습니다.


 

screens/FeedsScreen.js

import React from 'react';
import {View, StyleSheet} from 'react-native';

function FeedsScreen() {
  return <View style={styles.block} />;
}

const styles = StyleSheet.create({
  block: {},
});

export default FeedsScreen;

screens/CalendarScreen.js

import React from 'react';
import {View, StyleSheet} from 'react-native';

function CalendarScreen() {
  return <View style={styles.block} />;
}

const styles = StyleSheet.create({
  block: {},
});

export default CalendarScreen;

screens/SearchScreen.js

import React from 'react';
import {View, StyleSheet} from 'react-native';

function SearchScreen() {
  return <View style={styles.block} />;
}

const styles = StyleSheet.create({
  block: {},
});

export default SearchScreen;

screens/WriteScreen.js

import React from 'react';
import {View, StyleSheet} from 'react-native';

function WriteScreen() {
  return <View style={styles.block} />;
}

const styles = StyleSheet.create({
  block: {},
});

export default WriteScreen;

screens/MainTab.js

import React from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import FeedsScreens from './FeedsScreens';
import CalendarScreen from './CalendarScreen';
import SearchScreen from './SearchScreens';

const Tab = createBottomTabNavigator();

function MainTab() {
  return (
    <Tab.Navigator>
      <Tab.Screen name={'Feeds'} component={FeedsScreens} />
      <Tab.Screen name={'Calendar'} component={CalendarScreen} />
      <Tab.Screen name={'Search'} component={SearchScreen} />
    </Tab.Navigator>
  );
}

export default MainTab;

screens/RootStack.js

import React from 'react';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import MainTab from './MainTab';
import WriteScreen from './WriteScreen';

const Stack = createNativeStackNavigator();

function RootStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name={'MainTab'}
        component={MainTab}
        options={{headerShown: false}}
      />
      <Stack.Screen name={'Write'} component={WriteScreen} />
    </Stack.Navigator>
  );
}

export default RootStack;

네이트브 스택 네비게이터에서 MainTab 화면을 설정할 때

 

headerShown 값을 false로 설정하지 않으면 헤더가 중첩됩니다.

 

다 만들었다면 App.js에 RootStack 컴포넌트를 사용하는 코드를 작성합니다

 

App.js

import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import RootStack from './screens/RootStack';

function App() {
  return (
    <NavigationContainer>
      <RootStack />
    </NavigationContainer>
  );
}

export default App;

 

이런 허전한 화면을 채워주기 위해 MainTab 컴포넌트를 수정해주겠습니다.


책에 있는 createBottomTabNavigator의 문법이 업데이트 되면서 수정 되었네요.

 

import React from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import FeedsScreens from './FeedsScreens';
import CalendarScreen from './CalendarScreen';
import SearchScreen from './SearchScreens';
import Icon from 'react-native-vector-icons/MaterialIcons';

const Tab = createBottomTabNavigator();

function MainTab() {
  return (
    <Tab.Navigator
      screenOptions={{
        tabBarShowLabel: false,
        tabBarActiveTintColor: '#009688',
      }}>
      <Tab.Screen
        name={'Feeds'}
        component={FeedsScreens}
        options={{
          tabBarIcon: ({color, size}) => (
            <Icon name="view-stream" size={size} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'Calendar'}
        component={CalendarScreen}
        options={{
          tabBarIcon: ({color, size}) => (
            <Icon name="event" size={size} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'Search'}
        component={SearchScreen}
        options={{
          tabBarIcon: ({color, size}) => (
            <Icon name="search" size={size} color={color} />
          ),
        }}
      />
    </Tab.Navigator>
  );
}

export default MainTab;

 

수고하셨습니다.

반응형

댓글