[프로젝트-DediCats] Devlog-2

김대연·2020년 2월 5일
0

Project DediCats

목록 보기
3/16

이번 포스트에서는 어제 얘기했었던 디렉토리와 컴포넌트 아키텍쳐를 관한 내용이다.

.
├── App.js
├── README.md
├── app.json
├── babel.config.js
├── package-lock.json
├── package.json
├── node_modules
└── src
    ├── components
    │   ├── addCat
    │   │   ├── AddCatBio.js
    │   │   ├── AddCatForm.js
    │   │   └── AddCatMap.js
    │   ├── authInfo
    │   │   ├── AuthLoadingScreen.js
    │   │   ├── SignIn_Info.js
    │   │   └── SignUp_Info.js
    │   ├── catInfo
    │   │   ├── CatInfoTabs.js
    │   │   ├── CatProfile.js
    │   │   └── catTabs
    │   │       ├── CatAlbum.js
    │   │       ├── CatBio.js
    │   │       ├── CatComment.js
    │   │       ├── CatCommentList.js
    │   │       ├── CatFollower.js
    │   │       ├── CatFollowerList.js
    │   │       ├── CatPhoto.js
    │   │       ├── CatPost.js
    │   │       ├── CatPostInput.js
    │   │       └── CatPostList.js
    │   ├── main
    │   │   ├── BriefCatInfo.js
    │   │   ├── MainMap.js
    │   │   └── MainMarker.js
    │   └── my
    │       ├── MyCat.js
    │       ├── MyCatList.js
    │       ├── MyProfile.js
    │       ├── MyProfile_Elements.js
    │       └── PW_Elements.js
    ├── pages
    │   ├── AddCatModal.js
    │   ├── AddCatTab.js
    │   ├── CatInfo.js
    │   ├── ChangePW.js
    │   ├── EditMyProfile.js
    │   ├── Main.js
    │   ├── MyPage.js
    │   ├── SelectedPost.js
    │   ├── Signin.js
    │   └── Signup.js
    └── stores
        ├── CatStore.js
        ├── UserStore.js
        └── index.js

저번 포스트에 추가한 목업 페이지와 컴포넌트구조 링크를 바탕으로 만든 디렉토리이다.
이 중 목업 페이지와 pages를 바탕으로 react-navigation구조를 짰다. 먼저 전체적인 코드로는 이런 구조를 띄고 있다.

const MyPageStack = createStackNavigator(
  {
    MyPage,
    EditMyProfile,
    ChangePW,
  },
  {
    initialRouteName: 'MyPage',
  },
);

MyPageStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
  if (navigation.state.index > 0) {
    tabBarVisible = false;
  }

  return {
    tabBarVisible,
  };
};

const MainStack = createStackNavigator(
  {
    Main,
    CatInfo,
    SelectedPost,
  },
  {
    initialRouteName: 'Main',
  },
);

MainStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
  if (navigation.state.index > 0) {
    tabBarVisible = false;
  }

  return {
    tabBarVisible,
  };
};

const HomeTabs = createBottomTabNavigator(
  {
    AddCatTab,
    MainStack,
    MyPageStack,
  },
  {
    initialRouteName: 'MainStack',
    defaultNavigationOptions: {
      tabBarOnPress: ({ navigation, defaultHandler }) => {
        if (navigation.state.key === 'AddCatTab') {
          navigation.navigate('AddCatModal');
        } else {
          defaultHandler();
        }
      },
    },
  },
);

const AppStack = createStackNavigator(
  {
    Home: {
      screen: HomeTabs,
      navigationOptions: {
        headerShown: false,
      },
    },
    AddCatModal,
  },
  {
    initialRouteName: 'Home',
    modal: 'modal',
  },
);

const AuthStack = createStackNavigator(
  {
    'Sign In': {
      screen: Signin,
      navigationOptions: {
        headerShown: false,
      },
    },
    'Sign Up': Signup,
  },
  {
    initialRouteName: 'Sign In',
  },
);

const RootNavigator = createSwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    Auth: AuthStack,
    App: AppStack,
  },
  { initialRouteName: 'AuthLoading' },
);

const AppContainer = createAppContainer(RootNavigator);

구조가 아래서부터 위로 추가를 해서 나무 뿌리에서 가지가 뻗어나가는(?) 것과 같은데 아래서부터 설명해보고자 한다. 분리해서 설명하는 코드들도 아래서부터 읽는 것을 추천한다. 가지를 뻗는다고 상상하면 도움이 되기도 한다.

const AppStack = createStackNavigator(
  {
    Home: {
      screen: HomeTabs,
      navigationOptions: {
        headerShown: false,
      },
    },
    AddCatModal,
  },
  {
    initialRouteName: 'Home',
    modal: 'modal',
  },
);

const AuthStack = createStackNavigator(
  {
    'Sign In': {
      screen: Signin,
      navigationOptions: {
        headerShown: false,
      },
    },
    'Sign Up': Signup,
  },
  {
    initialRouteName: 'Sign In',
  },
);

const RootNavigator = createSwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    Auth: AuthStack,
    App: AppStack,
  },
  { initialRouteName: 'AuthLoading' },
);

const AppContainer = createAppContainer(RootNavigator);

먼저 RootNavigator는 말 그래도 가장 뿌리가 되는 네비게이터이고, 가장 뿌리가 되는 이 RootNavigatorcreateAppContainer()를 이용하여 컴포넌트화 시켜서 App.js에서 실행시킨다. 이 RootNavigator는 stack, tab 과는 다른 switch 네비게이터인데, stack처럼 페이지가 쌓이는 구조도 아닌, screen이 전환된다는 점에서 tab과도 비슷하다고 느껴질 수 있다. 하지만 tab처럼 병렬적 구조가 아닌 한 번에 하나의 screen을 보여주기 때문에 차이가 있다.

RootNavigator는 세가지 화면이 있는데, AuthLoading화면에서 토큰이 있는지 확인을 해서 토큰이 존재하지 않는다면 Auth로 보내 인증 절차(Sign Up/Sign In)를 거치게 하고, 토큰이 이미 존재한다면 App으로 보내 인증 절차를 생략하게 한다.

const HomeTabs = createBottomTabNavigator(
  {
    AddCatTab,
    MainStack,
    MyPageStack,
  },
  {
    initialRouteName: 'MainStack',
    defaultNavigationOptions: {
      tabBarOnPress: ({ navigation, defaultHandler }) => {
        if (navigation.state.key === 'AddCatTab') {
          navigation.navigate('AddCatModal');
        } else {
          defaultHandler();
        }
      },
    },
  },
);

App의 구성은 AddCatTab, MainStack, MyPageStack으로 이루어져 있는 HomeTabs와 modal창을 띄우는 AddCatModal이 있다.

defaultNavigationOptions: {
      tabBarOnPress: ({ navigation, defaultHandler }) => {
        if (navigation.state.key === 'AddCatTab') {
          navigation.navigate('AddCatModal');
        } else {
          defaultHandler();
        }
      },
    },

여기에서 AddCatTabAddCatModal의 이름이 비슷한데, 사실 AddCatTab을 터치했을 때 tab처럼 넘어가는게 아닌 새로운 창을 띄우기 위해 위처럼 빈 스크린으로 남겨두고 AddCatModal을 stack으로 쌓는 방법을 택했다.

const MyPageStack = createStackNavigator(
  {
    MyPage,
    EditMyProfile,
    ChangePW,
  },
  {
    initialRouteName: 'MyPage',
  },
);

MyPageStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
  if (navigation.state.index > 0) {
    tabBarVisible = false;
  }

  return {
    tabBarVisible,
  };
};

const MainStack = createStackNavigator(
  {
    Main,
    CatInfo,
    SelectedPost,
  },
  {
    initialRouteName: 'Main',
  },
);

MainStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
  if (navigation.state.index > 0) {
    tabBarVisible = false;
  }

  return {
    tabBarVisible,
  };
};

MainStack은 말 그래도 stack의 구조인데, 지도를 렌더하는 Main에서 마커를 선택하면 해당 마커에 관한 자세한 정보를 담은 CatInfo를 쌓게 되고, 그 중 하나의 포스트를 선택하면 SelectedPost를 또 쌓게 된다.

MainStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
  if (navigation.state.index > 0) {
    tabBarVisible = false;
  }

  return {
    tabBarVisible,
  };
};

참고로 위의 코드는 네비게이팅을 할 때 옵션을 정해주는 function으로 위 같은 경우는 stack으로 인해 쌓인 상위 구조의 header를 제거해주는 기능을 한다.

마지막으로 설명했었던 SelectedPost는 사실 4개의 tab으로 이루어진 화면을 구상중인데, 고정적으로 렌더되는 컴포넌트가 있어서 tab navigator보다는 Native Base의 tab을 이용하여 나타내기로 결정하였다.


다음 포스트는 이번 프로젝트에서 가장 큰 시간을 할애했던 react-native-maps 와 관련된 내용을 다룰 예정이다. 힘들게 적용한만큼 정리를 잘 해두어야겠다는 생각이 든다. 짧은 첫번째 프로젝트도 정신없었는데 두번째 프로젝트에서는 시간개념이 희미해졌다. 아직 갈길이 머니 정신차리고 힘을 내야한다. 내일은 오늘보다 더 유익한 하루이길.

0개의 댓글