react native(expo) 개발을 하다보면 모바일 ui가 중요하다는 것은 누구에게나 통용되는 사실일 것이다.
애니메이션을 넣고 버튼을 적절히 배치하고 디자인도 보기 좋게 만들어야 사람들이 쓴다.
다만 기술적으로 구현하기에 어려운 영역도 존재하고 모든 것을 일일이 구현하다 보면 핵심 기능 보단 ui/ux에 중점을 빠르게 개발하지 못할 것이다.
전에 초기에 쓴 스택은 gluestack-ui 였다 ui를 구성하기가 쉬웠으며 padding margin backgroundColor 와 같은 css 속성을 줄 수 있었다. 다만 성능상의 문제가 생길 정도로 무거웠으며 많은 컴포넌트가 겹치니까 더 문제가 발생했고 button 안에서 style을 위한 tag와 이벤트 발생 처리 tag가 겹쳐 가독성에 큰 문제가 발생했다.
그 문제를 해결하기 위해 난 styled-components를 활용하기로 했고 js로 파일을 불러오고 다시 css를 만드는 것 보단 linaria를 활용해 번들러에서 처리하여 이중처리를 방지하고자 했다. 다만 이때조차 문제가 발생한 건 ui/ux를 구성하는데 raw css를 사용해야 한다는 것이었고 맨 땅에 해딩하듯이 처음부터 구성해야 한다는 것이다. ## 현재 이야기와 문제점
성능상의 이점과 가독성 더하여 빠르게 개발할 수 있는 것 까지 모두 나에게 필요했다. 일단 내가 중점적으로 둬야 할 건 빨리 개발하는 것이었다. 그 다음이 성능이고 아무튼 전의 경험을 통해 확실히 안게 있다면
1. 모바일 개발은 ui, 기능, 이벤트 처리 코드로 나눠진다.
2. 이것들을 분리하지 않으면 가독성에 문제가 생긴다.
3. 맨땅에 해딩하듯 css 스타일을 처음부터 정하고 싶지 않았다.
4. 라이브러리 중에서 리소스를 많이 잡아먹는 것들이 있다.
5. 애니메이션을 넣기 위해 많은 코드를 짜야 한다.
이 정도로 요약이 가능했다. 나는 성능도 좋고 이벤트 처리를 할 수 있고 이를 분리할 수 있는 라이브러리를 찾아야 했다.

사이트에 들어가자 난 랜딩 페이지가 맘에 들었다. 더하여 아래로 내려 보니 벤치마크 결과에서 gluestack-ui의 성능을 최대 20배까지 앞선다고 한다. 내가 전에 썼던 게 성능 문제였고 맨 땅에 해딩하듯 디자인을 다시 하고 싶진 않았으니 나는 일단 이 문서에 들어가 어떻게 react native에 적용하는지 살펴봤다.
생각보다 매우 간단했다.
npx create tamagui
생각보다 매우 간단했다.
이렇게 명령어를 치면 앱 이름을 고르고 선택할 수 있는 창이 뜬다.

나는 기본 옵션을 선택했고 모듈이 설치되고 나서 3-4분 정도 걸렸다. 구성은 간단하고 빠르게 완료되었다.
나는 앱 개발을 하기 위해 expo를 활용했다. react-native 자체로 개발하다 보면 안드로이드, ios 폴더 내에 들어가 세팅을 해줘야 할때도 있다. 그게 귀찮아서 전 부터 expo에 세팅을 몰아 넣고 development mode를 활용하여 앱을 개발했다. 그리고 tamagui를 통해 구성된 프로젝트도 마찬가지로 apps/expo 안에 세팅이 있었고 나는 앱 개발 한 세팅을 그대로 갖다 붙였다.
expo/app.json
{
"expo": {
...,
"assetBundlePatterns": ["**/*"],
"ios": {
"infoPlist": {
"NSLocationAlwaysAndWhenInUseUsageDescription": "[CHANGEME] This app requires location always, even when the app is in the background",
"NSLocationWhenInUseUsageDescription": "[CHANGEME] This app requires location while in use",
"NSMotionUsageDescription": "[CHANGEME] This app uses motion-detection to determine the motion-activity of the device (walking, vehicle, bicycle, etc)",
"UIBackgroundModes": ["location", "fetch", "processing"],
"BGTaskSchedulerPermittedIdentifiers": [
"com.transistorsoft.fetch",
"com.transistorsoft.customtask"
]
},
"supportsTablet": true,
"bundleIdentifier": "com.yourprojectsname.app"
},
"android": {
"permissions": [
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.ACCESS_BACKGROUND_LOCATION",
"android.permission.FOREGROUND_SERVICE",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"
],
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF"
},
"package": "com.yourprojectsname.app"
},
"web": {
"favicon": "./assets/favicon.png"
},
"plugins": [
"expo-router",
"expo-font",
[
"react-native-background-geolocation",
{
"license": ""
}
],
[
"expo-gradle-ext-vars",
{
"googlePlayServicesLocationVersion": "21.1.0",
"appCompatVersion": "1.4.2"
}
],
"react-native-background-fetch",
[
"@rnmapbox/maps",
{
"RNMapboxMapsImpl": "mapbox",
"accessToken":
}
]
],
"experiments": {
"typedRoutes": true
}
}
}
지도 앱을 개발하다 보면 설정에 추가해줘야 될 게 많았다.rnmapbox가 google map에 비해 인기가 없는 것도 더하여 rn-background-gelocation도 유로 라이브러리라 레퍼런스가 많이 없다는 것도 이 세팅을 구성하는데 문제 였다. 아마 내 코드를 본다면 일부러 accessToken과 license만 비워 났으니 쓰면 좋겠다.
암튼 이렇게 expo 코드 안에 넣었다. 그리고 이 작업을 apps/expo 안에 들어가 라이브러리를 설치하고 가동했다.
전에 프로젝트의 루트 폴더에 가서 다운을 받았지만 이는 틀린 방법이었고 루트 폴더가 하는 역할은 packages안에 페이지를 apps 안에 있는 next와 expo에게 뿌려주는 역할 이었고. 이 디펜던시와 코드에 필요한 라이브러리는 각 apps안에서 설치 해야 했다.
오늘은 이렇게 설정을 했고 안드로이드, ios에서 모두 돌아가는 것을 확인하였다. 전에 쓰던 것과는 달라서 더 공부를 해야 겠지만 애니메이션을 쉽게 넣을 수 있고 코드도 간략해 질 수 있다면 큰 도움이 될 듯 했다.