👉🏻 글쓰기 버튼을 클릭하면 새로운 글 쓰기 화면이 아래 탭 내비게이터 전체를 가리면서 화면이 이동하게 만들고자 했다.
그러나, 다른 화면들과 마찬가지로 탭 내비게이터가 존재 한 상태로 화면이 이동되는 문제가 생겼다.
이 문제를 해결하기 위해, 화면 위에 화면을 쌓는 내비게이터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을 가리는 문제, 입력시 마다 사라졌다 생겼다 하는 키보드, 화면이 잘리지 않도록 고려, 화면 이동 방식 등등
하지만 그만큼 재미도 크기에 막히는 과정들이나 부분들을 정리해나가며 이어나갈 예정이다!