하당 탭 만들기

React Navigation에서 제공해주는 컴포넌트들…

  • BottomTabs : 기본 탭
  • MaterialBottomTabs : 아래쪽에 탭이 있고 물결 효과가 있음
  • Material Top Tabs : 위쪽에 탭이 있는 탭 네비게이터

우리는 BottomTab을 사용할 것임

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { ContentRoutes } from './routes';
import HomeScreen from '../screens/HomeScreen';
import ProfileScreen from '../screens/ProfileScreen';
import MapScreen from '../screens/MapScreen';
import ListScreen from '../screens/ListScreen';

const Tab = createBottomTabNavigator();

const ContentTab = () => {
	return (
		<Tab.Navigator>
			<Tab.Screen name={ContentRoutes.HOME} component={HomeScreen} />
			<Tab.Screen name={ContentRoutes.LIST} component={ListScreen} />
			<Tab.Screen name={ContentRoutes.MAP} component={MapScreen} />
			<Tab.Screen
				name={ContentRoutes.PROFILE}
				component={ProfileScreen}
			/>
		</Tab.Navigator>
	);
};

export default ContentTab;

위를 참조해서 만들면 된다.

option과 icon

<Tab.Navigator
            initialRouteName={ContentRoutes.PROFILE}
            screenOptions={{
                headerShown: false,
            }}
        >

첫 라우트 지정가능 header 보이고 안보이고등의 option지정 가능

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { ContentRoutes } from './routes';
import HomeScreen from '../screens/HomeScreen';
import ProfileScreen from '../screens/ProfileScreen';
import MapScreen from '../screens/MapScreen';
import ListScreen from '../screens/ListScreen';
import { MaterialCommunityIcons } from '@expo/vector-icons';

const Tab = createBottomTabNavigator();

const getTabBarIcon = ({ focused, color, size, name }) => {
	const iconName = focused ? name : `${name}-outline`;
	return <MaterialCommunityIcons name={iconName} size={size} color={color} />;
};

const ContentTab = () => {
	return (
		<Tab.Navigator
			initialRouteName={ContentRoutes.PROFILE}
			screenOptions={{
				headerShown: false,
			}}
		>
			<Tab.Screen
				name={ContentRoutes.HOME}
				component={HomeScreen}
				options={{
					tabBarIcon: props =>
						getTabBarIcon({ ...props, name: 'home' }),
				}}
			/>
			<Tab.Screen
				name={ContentRoutes.LIST}
				component={ListScreen}
				options={{
					tabBarIcon: props =>
						getTabBarIcon({ ...props, name: 'post' }),
				}}
			/>
			<Tab.Screen
				name={ContentRoutes.MAP}
				component={MapScreen}
				options={{
					tabBarIcon: props =>
						getTabBarIcon({ ...props, name: 'map' }),
				}}
			/>
			<Tab.Screen
				name={ContentRoutes.PROFILE}
				component={ProfileScreen}
				options={{
					tabBarIcon: props =>
						getTabBarIcon({ ...props, name: 'account' }),
				}}
			/>
		</Tab.Navigator>
	);
};

export default ContentTab;
  • tabBarIcon : 아이콘 넣어주면 됨
  • tabBarActiveTintColor : 선택된 색상
  • tabBarInactiveTintColor : 선택 안된 색상
  • tabBarShowLabel : 라벨 안보이게 하고 싶을 때 false
  • tabBarLabel : 라벨을 커스텀 할 수 있음.

작성화면으로 갔을 때, 아래 탭 숨기기

숨긴다기 보다는, 새로운 화면이 쌓는게 방법임.

글 작성 시 사진 추가 화면과 글 작성 화면

두개를 만들 것임

<Tab.Screen
	name={'AddButton'}
	component={AddButton}
	options={{ tabBarButton: () => <TabBarAddButton /> }}
/>

이렇게 tabBarButton 에다가 연결해두면 아예 버튼을 새로 만들 수 있고

이 버튼에서 새페이지 열리도록 만들었음.

updateProfile

  1. 일단 로그아웃 시 firebase에서도 로그아웃될 수 있도록 한다.
export const signOut = async () => {
	await signOutFirebase(getAuth());
};

위와 같이 signOut 함수를 이용하여 해결

  1. profile 업데이트 해준다.
const updateUserInfo = async userInfo => {
	try {
		await updateProfile(getAuth().currentUser, userInfo);
	} catch (error) {
		throw new Error('사용자 정보 수정에 실패했습니다.');
	}
};

FastImage

이미지 로컬파일시스템에 캐싱해서 사용하기

import { Image, StyleSheet, Text, View } from 'react-native';
import PropTypes from 'prop-types';
import { useEffect, useState } from 'react';
import * as Crypto from 'expo-crypto';
import * as FileSystem from 'expo-file-system';

const FastImage = ({ source, ...props }) => {
	const [uri, setUri] = useState(source.uri);

	useEffect(() => {
		(async () => {
			try {
				const hashed = await Crypto.digestStringAsync(
					Crypto.CryptoDigestAlgorithm.SHA256,
					source.uri,
				);
				const fileSystemUri = `${FileSystem.cacheDirectory}${hashed}`;

				const metadata = await FileSystem.getInfoAsync(fileSystemUri);
				if (!metadata.exists) {
					await FileSystem.downloadAsync(source.uri, fileSystemUri);
				}
				setUri(fileSystemUri);
			} catch (error) {
				setUri(source.uri);
			}
		})();
	}, [source.uri]);

	return <Image source={{ uri }} {...props} />;
};

FastImage.propTypes = {
	source: PropTypes.object.isRequired,
};

export default FastImage;