[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
console.log(frontendjigu( ☕️, 📱); // true

0개의 댓글