2023-08-17: React Native 학습 (1)
🤔 갑자기 왜 React-Native인가?
현재 회사에서 운영중인 서비스는 React-Native로 운영되고 있는 앱이다. 회사에서는 어찌됐든 프론트엔드 개발자는 모두 RN을 할 줄 알아야 했고, 나 역시 예외는 아니었어서 결국 피할 수 없는 운명에 처하게 되었다. 오 갓.
기간도 정해져있고, 모르는 것도 많은 상황 속에서 마음 속에서는 계속 불안증이 몰려왔다.
그도 그럴게, 맨땅에 헤딩해야하는 상황이 와버렸는데 공부할 시간도 부족하고… 어떻게 해야하나 정신적으로 몰려있던 상황 속에서 끙끙 앓던 며칠 후, 사수분과 다른 분들의 대화를 나누며 내린 결론은 ‘별 수 있나.. 어차피 해야할 운명이었으면, 일단 해봐야지..’이었다.
그래서 이번에 어차피 하는 거 공부한 내용들을 좀 정리해볼 수 있게 블로그를 오랜만에 켜봤다.
이번 시리즈는 RN을 공부하면서 알게 된 것들, 그리고 웹 개발과 어떤 면에서 다른지를 조금씩 서술해보고자 한다. 급하게 공부하는 느낌이 있어서 이해가 더딘 부분들도 분명히 있으니 그 부분에 관해서는 많은 분들의 도움을 받을 수 있으면 좋겠다.
ℹ️ 일단 React Native가 무엇인지 알아보자.
React Native는 Meta에서 만든 JavaScript 라이브러리인 React의 방식을 차용해서 앱을 개발할 수 있도록 도와주는 오픈 소스 프레임워크이다.
React Native가 추구하는 방향은 React 환경에서 네이티브 앱을 쉽게 개발할 수 있도록 하는 것이다. 다만, 웹이 아니기 때문에 JSX의 방식으로 개발을 하지만 HTML이나 CSS를 사용할 수 있는 것은 아니며, 그와 비슷한 태그들을 활용해서 적용하는 식이다.
이와 관련해서 공식 문서에서도 아래와 같은 말을 한다.
To work with React Native, you will need to have an understanding of JavaScript fundamentals. … While we do our best to assume no prior knowledge of React, Android, or iOS development, these are valuable topics of study for the aspiring React Native developer.
React Native을 활용하려면, 기본적인 JavaScript의 작업 사항들을 이해해야합니다. … 저희는 React, Android 또는 iOS 개발에 대한 사전 지식이 없다 가정하고 최선을 다하고 있습니다만, 이러한 주제는 React Native 개발자를 꿈꾸는 분들에게 유용한 학습 주제가 될 것입니다.
이번 시간에는 React Native를 이용한 라우팅 방식과 화면 구성 UI 요소들을 간단하게 짚어보 한다.
🛣️ React Native의 라우팅 컴포넌트
React Native의 라우팅을 활용하려면 React Navigation이라는 라이브러리를 사용해야한다.
해당 라이브러리를 통해 라우팅을 하는 방법은 크게 Stack과 Tap, 그리고 Drawer가 있다.
그 밖에도 onelink와 deeplink라는 방식이 있지만, 해당 방식은 추후에 다루도록 하겠다.
Stack
출저: https://medium.com/walmartglobaltech/introduction-to-react-native-navigation-83ac8903ddad 위의 이미지와 같이 화면을 연달아 쌓아올리는 방식이다. 다른 의미로 말하면 레이어를 쌓아 올리는 구조라고 보면 될 것이다.
자료 구조의 방식처럼 Stack을 쌓아 올리고 창 하나를 지울 때마다 가장 최근의 창을 지워나가는 식이기에 Stack이라고 부르는 듯 하다.
Tap
출저: https://medium.com/walmartglobaltech/introduction-to-react-native-navigation-83ac8903ddad 하단에 있는 버튼 등을 눌러서 다른 화면으로 전환하는 방식이다. 같은 레이어 내에서 화면 전환을 해야 한다면 이 방식을 이용하면 된다.
Drawer
출저: https://medium.com/walmartglobaltech/introduction-to-react-native-navigation-83ac8903ddad Drawer는 흔히 말하는 좌측/우측 상단의 버튼을 눌러 밀려 나오는 버튼을 생각하면 된다. 서랍장이라는 의미답게 서랍을 여닫는 느낌으로 밀려 나오고, 닫히는 스크린이다.
페이지 내에서 수많은 메뉴를 보일 수 없으므로 전체 메뉴를 보여줘야할 때, 이 Drawer를 통해서 전체 메뉴를 노출시키게 한다.
<예시>
import * as React from 'react'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; const Stack = createNativeStackNavigator(); const MyStack = () => { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} options={{title: 'Welcome'}} /> <Stack.Screen name="Profile" component={ProfileScreen} /> </Stack.Navigator> </NavigationContainer> ); };
🖥️ React Native의 화면 구성 컴포넌트
HTML의 element처럼 React Native도 화면을 구성하는 요소, 컴포넌트가 존재한다. HTML처럼 다양하지는 않지만, 앱 만의 특징을 가진 컴포넌트들을 잘 활용하면 큰 도움이 될 것이다.
Screen- 단어 그대로 화면 자체를 가리키며, 화면의 한 단위를 가리킨다.
View- HTML로 따지면
div와 같은 존재이다. - UI를 구축하는 가장 기본적인 화면 요소이며, 기본적으로
Flex가 내장되어있는 상태이다. 웹과 다르게Flex의Direction은Column이다.
- HTML로 따지면
ScrollView- 웹에서는 기본 단위로
div의Height가 길어지면 스크롤이 생기지만 앱은 그렇지 않다. 따라서 Scroll이 다뤄지는 영역을 따로 정해줘야하는데, 이 때 사용하는 것이ScrollView이다.
- 웹에서는 기본 단위로

KeyboardAvoidingView웹에서 모바일 경험을 하다보면 불편하게 느껴지는 것 중 하나는
Input등을 통해 내용을 입력할 때, 터치 키보드가 출력되면서 입력 요소가 가려지는 부분일 것이다.React Native에서는 이러한 문제를 해결하기 위해
KeyboardAvoidingView를 제공한다.이 컴포넌트가 감싸는 영역은 하단에서 올라오는 키보드의 영향을 받지 않게 된다.

FlatList- JavaScript로 비교하자면
map메소드를 통해서 리스트를 나열하는 용도로 쓰이는 태그이다.
즉, 양이 많은 요소들을 나열해야할 때 쓰이는 친구인데 이 친구의 가장 큰 장점 중 하나는
ScrollView의 기능을 가지고 있으면서도, 스크롤을 내림으로서 이벤트를 발동해 무한 스크롤등을 자연스럽게 구현할 수 있는데에 있다.[f:id:develop_neoguri:20240723000006p:plain] React Native 내용을 찾아보면서 이 친구에 대한 내용이 꽤나 중요하다는 것을 깨달았으므로 추후에 이 친구만 따로 정리해보고자 한다.- JavaScript로 비교하자면
SectionListFlatList와 동일하지만, 다른 점이라면 HTML의element중에section과 동일한 의미를 지니고 있다.
FlatList는 단순히 리스트를 나열하기 위한 용도라고 한다면,SectionList는 단어 그대로 구역을 나눠주는 역할을 한다.FlastList를 그룹핑한다고 생각하면 편하며,SectionHeader를 활용해 그룹핑한 컴포넌트에 제목을 붙일 수도 있다.[f:id:develop_neoguri:20240723000012p:plain]VirtualizedListFlatList와SectionList를 전부 포함하고 있는 컴포넌트라고 보면 되는데, 실질적으로 쓰이는 경우는 거의 없으며 접근성 측면에서도FlatList와SectionList를 활용하는 게 더 좋은 듯 하다.
Text- HTML의
h1,h2,p,span등 문장을 입력하기 위한 컴포넌트이다.
- HTML의
Image- HTML의
imgelement를 떠올리면 된다. - 안드로이드의 경우에는 GIF와 Webp를 지원해주고 있지 않으므로 별도의 모듈을 설정해줄 필요가 있다.
- HTML의
ImageBackgrounddiv나section등에 쓰이는 style 요소 중background-image속성이 있는데 이를 컴포넌트화한 것으로 생각하면 된다.
Modal- 웹과 다르게 React Native는
Modal을 하나의 컴포넌트로 사용하도록 제공해준다. - 실제 사용 시, 현재 보고 있는 스크린 위에 팝업처럼 띄워줄 모달을 보여줄 수 있다.
- 웹과 다르게 React Native는
ActivityIndicator간단하게 말하자면 로더를 컴포넌트화한 것으로 여기면 된다.

StatusBar앱의 기본 구성 중 하나인 상단에 보여지는 핸드폰의 상태들을 보여주는 영역이다.

✅ React Native의 상호 작용 컴포넌트
Button우리가 흔히 생각하는 상호 작용 요소의 대표격인 버튼, 그 자체이다.

onClick같은 이벤트는onPress로 적용되어있으며, 기존 웹과 다르게onPress가 필수 속성으로 갖춰져있다. 또한title속성도 필수 속성으로 적용되어 있다.
Pressable(신규 요소)Pressable은 React Native에서 가장 최근에 생긴 컴포넌트인데, 설명하자면Button이벤트가 집대성된 컴포넌트라고 보는 게 좋을 것 같다. React Native 사이트에서 제공하는 아래의 이미지를 보자.[f:id:develop_neoguri:20240723000234j:plain] `Pressable`은 버튼 하나에 다양한 이벤트를 부여하고 싶을 때에 쓰이는 컴포넌트이다. 이 컴포넌트를 이용하면 민감한 이벤트들에 작동해야하는 요소를 보다 세분화하여 동작 관리를 할 수 있다는 것이 가장 큰 장점이다. [f:id:develop_neoguri:20240723000241p:plain]
TouchableHighlightTouchable이 적힌 컴포넌트는 버튼과 동작이 비슷하지만, 버튼을 위한 컴포넌트는 아니며 각 화면 요소들에 터치 시에 일어나는 이벤트들을 상호작용해주는 컴포넌트이다.TouchableHighlight컴포넌트는 특정 컴포넌트를 터치 시, 해당 컴포넌트가 강조되도록 highlight를 부여해주는 컴포넌트이다.
TouchableOpacityTouchableOpacity컴포넌트는 opacity라는 단어와 동일하게 터치 시, 투명도가 변화되도록 부여해주는 컴포넌트이다.
TouchableWithoutFeedbackTouchableWthoutFeedback컴포넌트는 Touch 이벤트가 발생하지만, 이벤트와 관련하여 어떠한 효과도 발생하지 않도록 하는 컴포넌트이다.
TextInput웹에서도 가장 중요한
Form과 관련한Input요소이다.
React Native에서는 이
Input요소가Input외에도TextArea의 역할 등도 병행하고 있다.해당 컴포넌트와 관련해서는
FlatList만큼이나 중요한 만큼, 두 컴포넌트를 추후에 다시 한 번 더 정리하는 시간을 가져보도록 하겠다.
Switch흔히 iPhone의 감성이라 불리우는 그 스위치 생각하면 되겠다.

출저: https://medium.com/timeless/react-native-reanimated-switch-83c331af7877 Button과 같은 요소인데,Toggle로 편하게 쓸 수 있도록 구성되어있다.<Switch trackColor={{false: '#767577', true: '#81b0ff'}} thumbColor={isEnabled ? '#f5dd4b' : '#f4f3f4'} ios_backgroundColor="#3e3e3e" onValueChange={toggleSwitch} value={isEnabled} />on/off 색상은 물론, 스위치 색상도 정할 수 있으며
onValueChange이벤트로 스위치 상태에 따른onChange기능도 제공한다.
RefreshControlTwitter를 하는 사람이라면 익숙한 ‘쓱뽕쓱뽕’ 같이 화면을 아래로 드래그하여 내용을 갱신하는데, 이 컴포넌트는 그 동작을 적용하는 컴포넌트이다.

출저: https://stackoverflow.com/questions/54934513/offset-refreshcontrol-in-react-native 해당 컴포넌트는 화면 요소 컴포넌트 속에 있는
refreshControl속성에 배치함으로서 screen refresh를 유도할 수 있다.const App = () => { const [refreshing, setRefreshing] = React.useState(false); const onRefresh = React.useCallback(() => { setRefreshing(true); setTimeout(() => { setRefreshing(false); }, 2000); }, []); return ( <SafeAreaView style={styles.container}> <ScrollView contentContainerStyle={styles.scrollView} refreshControl={ **<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />** }> <Text>Pull down to see RefreshControl indicator</Text> </ScrollView> </SafeAreaView> ); };필수 속성으로
refreshing을 가지는데, 해당 컴포넌트가 동작할 때 어떤 행동을 취할 것일지를 적용하는 속성이다.
🍎 React Native의 iOS 호완 컴포넌트
아래의 컴포넌트는 React Native 내에서도 iOS에서만 적용되는 요소이다.
InputAccessoryViewTextInput 요소를 탭하면, 핸드폰에서 키보드가 떠오르는 것을 볼 수 있을 것이다.
ReactNative에서는 이때 떠오르는 키보드 위에 붙이고 싶은 컴포넌트가 있다면 해당 컴포넌트를 활용해 보여줄 수 있도록 한다.
해당 컴포넌트로 감싼 내용들은 TextInput을 탭할 시 키보드 위에 부착된다.

SafeAreaView- 최신 iPhone으로 갈 수록 Notify 디자인 영역이 독특하게 된 것을 볼 수 있을 것이다.
최대한 스크린 영역을 활용할 수 있게 하기 위해 내린 조치로 여겨지는데, 이로 인해 Notify 영역을 제외하고 기능을 이용할 수 있도록 하는 컴포넌트가 바로
SafeAreaView이다. 해당 컴포넌트를 활용하면 Notify 영역을 제외한 나머지 영역을 Screen View 영역으로 잡아주는 이점이 있다.

- 최신 iPhone으로 갈 수록 Notify 디자인 영역이 독특하게 된 것을 볼 수 있을 것이다.
최대한 스크린 영역을 활용할 수 있게 하기 위해 내린 조치로 여겨지는데, 이로 인해 Notify 영역을 제외하고 기능을 이용할 수 있도록 하는 컴포넌트가 바로
🤖 React Native의 Android 호완 컴포넌트
아래의 컴포넌트는 React Native 내에서도 Android에서만 적용되는 요소이다.
DrawerLayoutAndroid라우팅 관련으로 drawer와 관련한 컴포넌트인데 Android와 관하여 이 Drawer를 사용하는 영역을 지정해주는 컴포넌트이다.

출저: https://livebook.manning.com/concept/react-native/drawerlayoutandroid 해당 컴포넌트 내에서 버튼을 배치하고 활용하는 식으로 drawer 컴포넌트를 좀 더 원활하게 이용할 수 있다.
import React from 'react'; import {View, StyleSheet, Button, Alert} from 'react-native'; const App = () => { const createTwoButtonAlert = () => Alert.alert('Alert Title', 'My Alert Msg', [ { text: 'Cancel', onPress: () => console.log('Cancel Pressed'), }, {text: 'OK', onPress: () => console.log('OK Pressed')}, ]); const createThreeButtonAlert = () => Alert.alert('Alert Title', 'My Alert Msg', [ { text: 'Ask me later', onPress: () => console.log('Ask me later pressed'), }, { text: 'Cancel', onPress: () => console.log('Cancel Pressed'), }, {text: 'OK', onPress: () => console.log('OK Pressed')}, ]); return ( <View style={styles.container}> <Button title={'2-Button Alert'} onPress={createTwoButtonAlert} /> <Button title={'3-Button Alert'} onPress={createThreeButtonAlert} /> </View> ); }; export default App;
TouchableNativeFeedback- React Native에서는
Touchable컴포넌트 관련으로 Android에서만 쓰이는 컴포넌트인TouchableNativeFeedback를 제공해주고 있다. - 해당 컴포넌트로 감싼 영역에 정확하게 터치를 한 상태에서만 피드백이 발생하도록 하는 컴포넌트인데, 이벤트 동작 조건이 민감할 경우에 활용되는 컴포넌트인 듯 하다.
다면, 현재 React Native에서는 해당 컴포넌트를 포함하여
Touchable과 관련하여 다양한 상호작용을 고려한다면Pressable로 관리할 수 있으니 이를 활용하라고 권장하고 있다.If you're looking for a more extensive and future-proof way to handle touch-based input, check out the Pressable API.
- React Native에서는