[React Native] 구현시 고민했던 부분들 - Tab Navigator, 여러 이미지 캐싱

fejigu·2023년 2월 28일
2

React Native

목록 보기
7/11
post-thumbnail

🔥 새로운 화면 이동시 탭 내비게이터 가리기

👉🏻 글쓰기 버튼을 클릭하면 새로운 글 쓰기 화면이 아래 탭 내비게이터 전체를 가리면서 화면이 이동하게 만들고자 했다.

그러나, 다른 화면들과 마찬가지로 탭 내비게이터가 존재 한 상태로 화면이 이동되는 문제가 생겼다.

이 문제를 해결하기 위해, 화면 위에 화면을 쌓는 내비게이터 native stack navigator를 사용하여 화면을 이동할 때 화면 위에 화면을 쌓을 수 있었다.

이렇게 하려면 ContentTab.js를 화면으로 사용해야했다. ContentTab.js 컴포넌트를 Screen 컴포넌트의 컴포넌트에 설정해서 사용하는 것이다. (Tab navigator 역할을 하는 contentTab은 컴포넌트이다)

//MainStack.js
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { WHITE } from '../colors';
import SelectPhotosScreen from '../screens/SelectPhotosScreen';
import ContentTab from './ContentTab';
import { MainRoutes } from './routes';
const Stack = createNativeStackNavigator();
const MainStack = () => {
  return (
    <Stack.Navigator
      screenOptions={{
        contentStyle: { backgroundColor: WHITE },
        headerShown: false,
      }}

      //ContentTab를 컴포넌트로 설정
      <Stack.Screen name={MainRoutes.CONTENT_TAB} component={ContentTab} />
      <Stack.Screen name={MainRoutes.SELECT_PHOTOS} component={SelectPhotosScreen} />
    </Stack.Navigator>
  );
};
export default MainStack;
//routes.js
//화면 이름을 관리
export const AuthRoutes = {
    SIGN_IN: 'SignIn',
    SIGN_UP: 'SignUp',
  };
  export const MainRoutes = {
    CONTENT_TAB: 'ContentTab',
    SELECT_PHOTOS: 'SelectPhotos',
  };
  export const ContentRoutes = {
    HOME: 'Home',
    LIST: 'List',
    MAP: 'Map',
    PROFILE: 'Profile',
  }



🔥 여러 이미지들을 캐싱할 때 처리

👉🏻 지금까지는 이미지 캐싱 할 때, 아이콘 정도 한개의 이미지를 사용했기에 async-await를 사용하여 캐싱을 처리했었다.

하지만 홈 화면에서 여러 이지미들을 캐싱해야 했고, 그러기 위해서는 async-await를 사용하려 처리하는 것보다 Promise.all을 사용하는 것이 효율적일 것 같아 수정하게 되었다.

왜냐 Promise.all은 전달된 모든 비동기 함수가 완료된 후에, 전체 결과를 담은 배열을 반환하기 때문이다.

import { NavigationContainer } from '@react-navigation/native';
import { useEffect, useState } from 'react';
import { onAuthStateChanged } from '../api/auth';
import { useUserState } from '../contexts/UserContext';
import AuthStack from './AuthStack';
import MainStack from './MainStack';
import { Asset } from 'expo-asset';
import { initFirebase } from '../api/firebase';
import * as SplashScreen from 'expo-splash-screen';
//여러 이미지들 
const ImageAssets = [
  require('../../assets/main.png'),
  require('../../assets/home-clock.png'),
  require('../../assets/home-map.png'),
  require('../../assets/icon.png'),
];
const Navigation = () => {
  const [user, setUser] = useUserState();
  const [isReady, setIsReady] = useState(false);
  useEffect(() => {
    (async () => {
      try {
        await SplashScreen.preventAutoHideAsync();
        //Promise.all로 동시에 처리
        await Promise.all(
          ImageAssets.map((image) => Asset.fromModule(image).downloadAsync())
        );
        initFirebase();
        const unsubscribe = onAuthStateChanged((user) => {
          if (user) {
            setUser(user);
          }
          setIsReady(true);
          unsubscribe();
        });
      } catch (e) {
        // eslint-disable-next-line no-console
        console.log(e);
        setIsReady(true);
      }
    })();
  }, [setUser]);
  const onReady = async () => {
    if (isReady) {
      await SplashScreen.hideAsync();
    }
  };
  if (!isReady) {
    return null;
  }
  return (
    <NavigationContainer onReady={onReady}>
      {user.uid ? <MainStack /> : <AuthStack />}
    </NavigationContainer>
  );
};
export default Navigation;



🔎 회고

👉🏻 지금까지 React Native를 학습하고 구현을 하면서 느낀 것은 웹보다 더 섬세하다는 것이다. 더 고려해야하는 부분들이 많다고 느꼈다. 구현 전에는 생각하지 못했거나 당연하다고 생각했던 부분들에 막히고 고민하고 있는 것이다. ex) input에 작성을 하려고 키보드가 나타나고 , 키보드가 input을 가리는 문제, 입력시 마다 사라졌다 생겼다 하는 키보드, 화면이 잘리지 않도록 고려, 화면 이동 방식 등등

하지만 그만큼 재미도 크기에 막히는 과정들이나 부분들을 정리해나가며 이어나갈 예정이다!

profile
신규 서비스의 기획부터 개발, 운영까지 전 과정을 경험한 주니어 📱

0개의 댓글