인프런 강의 중 맛집 지도앱 만들기 (React Native + NestJS)에 대한 강의를 수강하던 중 지도에 대한 기능이 어느정도 구현되었는데, 너무 많은 라이브러리가 추가되어 이들을 하나씩 명확히 짚고 넘어가려고 한다. 하나씩 짚고 넘어가보자.
현재 "5-7. 환경변수 설정하기" 기준으로 설치된 라이브러리는 다음과 같다.
"dependencies": {
"@react-native-community/geolocation": "^3.3.0",
"@react-native-community/slider": "^4.5.2",
"@react-native-masked-view/masked-view": "^0.3.0",
"@react-navigation/drawer": "^6.6.6",
"@react-navigation/native": "^6.1.9",
"@react-navigation/stack": "^6.3.20",
"@tanstack/react-query": "^5.50.1",
"axios": "^1.7.2",
"react": "18.2.0",
"react-native": "0.72.6",
"react-native-config": "^1.5.2",
"react-native-date-picker": "^5.0.4",
"react-native-encrypted-storage": "^4.0.3",
"react-native-gesture-handler": "^2.13.4",
"react-native-image-crop-picker": "^0.41.2",
"react-native-maps": "1.14.0",
"react-native-permissions": "^4.1.5",
"react-native-reanimated": "^3.5.4",
"react-native-safe-area-context": "^4.7.4",
"react-native-screens": "^3.27.0",
"react-native-vector-icons": "^10.1.0"
},
각 라이브러리의 역할에 대해 우선 알아보자.
import Geolocation from '@react-native-community/geolocation';
Geolocation.getCurrentPosition(
info => {
const {latitude, longitude} = info.coords;
setUserLocation({latitude, longitude});
setIsUserLocationError(false);
},
() => {
setIsUserLocationError(true);
},
{
enableHighAccuracy: true,
},
);
<Slider
value={score}
onValueChange={onChangeScore}
step={1} // 슬라이더 단계 값
minimumValue={1} // 최소 값
maximumValue={5} // 최대 값
minimumTrackTintColor={pink_700} // 버튼 왼쪽 트랙 색상
maximumTrackTintColor={gray_300} // 버튼 오른쪽 트랙 색상
thumbTintColor={gray_100} // 그립 색상
/>
@react-navigation/stack
라이브러리를 추가할 때 주로 함께 설치되는데, 헤더에 UIkit 스타일 애니메이션을 사용하기 위해 필요한 라이브러리이다. (현재 강의 프로젝트에서는 필요없는 거 같은데 왜 설치되있지? 지워야겠다.)react-native-gesture-handler
와 react-native-reanimated
라이브러리를 설치해야만 한다.import {createDrawerNavigator} from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
<Drawer.Navigator>
<Drawer.Screen name={...} component={...} />
<Drawer.Screen name={...} component={...} />
<Drawer.Screen name={...} component={...} />
</Drawer.Navigator>
import { NavigationContainer } from '@react-navigation/native';
function App() {
return (
<NavigationContainer>
{Stack, Drawer 등의 네비게이션 위치}
</NavigationContainer>
)
}
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
<Stack.Navigator>
<Stack.Screen name={...} component={...} />
<Stack.Screen name={...} component={...} />
<Stack.Screen name={...} component={...} />
</Stack.Navigator>
process.env
)로 접근이 불가능하고, RN 애플리케이션을 네이티브 코드로 컴파일하는 번들링 과정에 환경 변수를 직접 포함하는 것은 쉽지 않은 방법입니다. -> 라이브러리 사용 권장import Config from 'react-native-config';
console.log(Config.TEST)
import DatePicker from 'react-native-date-picker';
<DatePicker
mode="date"
confirmText={BLACK} // 텍스트 색상
date={date}
onDateChange={onChangeDate}
locale="ko"
/>
EncryptedSharedPreferences
and iOS' Keychain
import EncryptedStorage from 'react-native-encrypted-storage';
const setEncryptStorage = async <T>(key: string, date: T) => {
await EncryptedStorage.setItem(key, JSON.stringify(date));
};
const getEncryptStorage = async (key: string) => {
const storedData = await EncryptedStorage.getItem(key);
return storedData ? JSON.parse(storedData) : null;
};
const removeEncryptStorage = async (key: string) => {
const data = await getEncryptStorage(key);
if (data) {
await EncryptedStorage.removeItem(key);
}
};
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import 'react-native-gesture-handler';
AppRegistry.registerComponent(appName, () => App);
const onSelectImage = () => {
ImagePicker.openPicker({
mediaType: 'photo',
multiple: true,
includeBase64: true,
maxFiles: 5,
cropperChooseText: '완료',
cropperCancelText: '취소',
})
.then(images => {
const formData = getFormDataImages(images);
uploadImages.mutate(formData, {
onSuccess: data => {
addImageUris(data);
},
});
})
.catch(error => {
if (error.code === 'E_PICKER_CANCELLED') {
return;
}
});
};
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';
<MapView provider={PROVIDER_GOOGLE}>
<Marker coordinate={...} />
</MapView>
Info.plist
에서 꼼꼼하게 작성하자.@react-navigation/drawer
라이브러리를 설치할 때 drawer 상호 작용을 조금 더 유연하게 이끌어내기 위해 함께 설치한다.import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
const inset = useSafeAreaInsets();
<SafeAreaView>
<Pressable style={{ top: inset.top || 20 }}>
<Text>버튼인 척</Text>
</Pressable>
</SafeAreaView>
@react-navigation/native
를 설치할 때 함께 설치하는데, 해당 라이브러리는 RN에 네이티브 네비게이션 컨테이너 컴포넌트를 노출하는 것을 목표로 한다. (즉, 독립 실행용으로 설계된 게 아니다)import Ionicons from 'react-native-vector-icons/Ionicons';
<Ionicons name="menu" color={WHITE} size={24} />