요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

본문은 요즘IT와 번역가 윌리(Willy)가 함께 만든 해외 번역 콘텐츠입니다. 소프트웨어 엔지니어인 필자 Dan Neciu는 개발뿐만 아니라 각종 UX/테스트 사례 분석으로 UX를 더 잘 이해하기 위해 노력하고 있습니다. 이번 글은 리액트 네이티브 개발자들이 겪는 가장 빈번한 문제를 알아보고, 이에 대한 해결책을 모색하기 위한 방법을 예제와 함께 설명하고 있습니다.

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

개발

리액트 네이티브 개발자들이 겪는 가장 빈번한 5가지 문제와 해결책

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

 

본문은 요즘IT와 번역가 윌리(Willy)가 함께 만든 해외 번역 콘텐츠입니다. 소프트웨어 엔지니어인 필자 Dan Neciu는 개발뿐만 아니라 각종 UX/테스트 사례 분석으로 UX를 더 잘 이해하기 위해 노력하고 있습니다. 이번 글은 리액트 네이티브 개발자들이 겪는 가장 빈번한 문제를 알아보고, 이에 대한 해결책을 모색하기 위한 방법을 예제와 함께 설명하고 있습니다.

 

리액트 네이티브로 모바일 앱을 개발할 때 자주 마주치는 문제와 그에 대한 해결책

 

리액트 네이티브
리액트 네이티브 개발자들이 겪는 가장 빈번한 5가지 문제와 해결책

 

지난 몇 년간 모바일 개발의 세계는 안드로이드와 스위프트[1]의 독무대였습니다. 하지만 지금은 자바스크립트를 사용하는 아이오닉(Ionic)[2]과 같은 하이브리드 프레임워크나 리액트 네이티브(React Native)[3]와 같은 네이티브 프레임워크로 그 중심축이 이동했습니다.

 

리액트 네이티브는 메타(구 페이스북)에서 만든 오픈소스 UI 소프트웨어 프레임워크입니다. 개발자는 리액트 프레임워크를 사용하여 안드로이드, 안드로이드 TV, iOS, macOS, tvOS, 웹, 윈도우즈 및 UWP용 네이티브 애플리케이션을 개발할 수 있습니다.

 

하지만 리액트 네이티브는 리액트나 뷰(Vue)와 같은 다른 자바스크립트 라이브러리와 비교하면 커뮤니티가 크지 않으며, 개발 과정에서 마주치는 문제에 대한 해결책을 찾는데 종종 어려움을 겪게 됩니다.

 

지금부터 리액트 네이티브 개발에서 가장 빈번하게 부딪히는 난관을 어떻게 해결할 수 있는지 구체적인 예제를 통해 알아보도록 하겠습니다.

 

 

1. 애플 스토어 커넥트 스크린샷

애플 스토어 커넥트
애플 스토어 검토 프로세스

 

리액트 네이티브 앱을 개발할 때 대부분 실제 장치에 배포하기 전 시뮬레이터를 사용하여 앱을 테스트하게 됩니다. Xcode 시뮬레이터를 사용해 봤다면 앱스토어서 요구하는 크기와 해상도의 스크린샷을 만드는 것이 얼마나 어려운 일인지 아실 것입니다.

 

구글 플레이(Google Play)에서는 이러한 절차가 간단하고 시뮬레이터에서 만든 스크린샷을 업로드하는 것이 쉬웠지만, 앱스토어에서는 원하는 비율의 스크린샷을 얻기가 힘들었습니다.

 

6.5인치 아이폰은 2688x1242 또는 2778x1284의 해상도가 필요합니다. 저는 다양한 옵션과 디바이스 에뮬레이터를 사용해봤지만 모두 실패했습니다. 그리고 여기서 마침내 답을 얻게 됐습니다.

 

다음과 같은 방식으로 원하는 해상도를 얻을 수 있습니다.

  • 시뮬레이터를 물리적 크기(physical size)로 설정: Window > Physical Size (단축키: command + 1)
  • 고품질 그래픽 설정: Debug > Graphics Quality Override > High Quality
  • 6.5인치 아이폰의 경우 아이폰 프로를 사용할 것. (저는 아이폰 11 프로를 사용했습니다.)
  • 5.5인치 아이폰은 아이폰 8 이상의 시뮬레이터를 사용할 것.
  • 아이패드 프로(3세대 혹은 2세대)는 아이패드 프로 시뮬레이터(12.9인치, 3세대)를 사용할 것.

 

 

2. 폰트 문제 해결하기

폰트 문제 해결
(출처: Brett Jordan - Unsplash)

 

리액트 네이티브는 안드로이드에서 'Roboto', iOS에서 'San Francisco'를 각 플랫폼의 기본 글꼴로 사용하고 있습니다. 그러나 디자이너는 대부분 앱의 전반적인 디자인에 어울리는 다른 글꼴을 사용하는 것을 선호합니다.

 

만약 구글 폰트를 사용하기 원한다면 크게 고민할 것이 없습니다. 간단하게 expo-google-fonts 패키지를 사용하면 됩니다.

 

expo install expo-google-fonts로 패키지를 설치한 후 다음과 같이 사용하면 됩니다.

 

import {
 useFonts,
 Lato_400Regular,
 Lato_900Black,
 Lato_700Bold,
} from '@expo-google-fonts/lato';
export default function App() {
 const isLoadingComplete = useCachedResources();
 const colorScheme = useColorScheme();
 let [fontsLoaded] = useFonts({
   Lato_400Regular,
   Lato_900Black,
   Lato_700Bold,
 });
 if (!isLoadingComplete || !fontsLoaded) {
   return <AppLoading />;
 } else {
   return (
     <SafeAreaProvider>
       <Navigation colorScheme={colorScheme} />
       <StatusBar />
     </SafeAreaProvider>
   );
 }
}

 

위의 코드는 글꼴을 불러오고 앱을 시작하기 전에 로드되었는지 확인합니다. 이제 여러분의 스타일시트에서 아래와 같이 간단하게 사용할 수 있습니다.

 

fontFamily: 'Lato_400Regular'

 

expo-google-fonts와 관련해서 제가 겪었던 한 가지 문제는, 아래와 같이 실수로 전체 프로젝트를 가져와 Lato 글꼴뿐만 아니라 모든 글꼴을 로드할 때였습니다.

 

import { Lato_400Regular } from '@expo-google-fonts/dev';

 

이것은 web-view나 안드로이드 시뮬레이터에서 문제없이 동작하지만, 아이폰에서는 모든 글꼴을 한 번에 로드하려고 시도하며 메모리 제한으로 앱에 오류가 발생합니다. 따라서 다음과 같이 필요한 글꼴만 가져오는지 확인하는 것이 중요합니다.

 

import { Lato_400Regular } from '@expo-google-fonts/lato';

 

 

3. 모바일 장치의 로컬 스토리지와 쿠키

로컬 스토리지
(출처: Christina Branco - Unsplash)

 

처음에 저는 프론트엔드 개발 경험을 떠올리며 거의 모든 작업에 쿠키와 로컬 스토리지를 무분별하게 사용하려 했습니다.

 

사용자 정보를 어디엔가 저장해놓고 나중에 꺼내써야 한다면? 쿠키(Cookie)를 사용하면 되죠! 거의 변경되지 않는 요청은 어디에 저장해놔야 할까요? 로컬 스토리지(Local Storage)!

 

프론트엔드에서는 당연한 일이었기에, 저는 모바일 앱에서도 인증에 사용되는 베어러 토큰(Bearer Token)[4]과 사용자 정보 객체를 로컬 스토리지에 저장했습니다. 하지만 같은 방식으로 에뮬레이터에서 테스트해보니, 토큰이 유지되지 않고 모든 요청에 포함되는 베어러 문자열이 비어있다는 사실을 알게 됐습니다.

 

조사해보니, 이러한 문제를 해결해 줄 수 있는 패키지인 react-native-async-storage/async-storage를 찾았습니다.

 

패키지를 설치한 후 expo install react-native-async-storage/async-storage를 사용하면 우리가 일반적으로 사용하는 로컬 스트로지처럼 쉽게 사용할 수 있습니다.

 

try {
   await AsyncStorage.setItem('@token', result.data.token);
   const jsonValue = JSON.stringify(result.data);
   await AsyncStorage.setItem('@user_Object', jsonValue);
 } catch (e) {
   console.log(e);
 }
try {
 const value = await AsyncStorage.getItem('@user_Object');
 if (value !== null) {
    const userObjectParsed = JSON.parse(value);
 }
} catch (e) {
 // error reading value
}
 

 

JSON.stringify()JSON.parse() 함수가 사용되는 방식에 주목하세요. AsyncStorage.setItem() 함수에 문자열 대신 JSON을 전달하면 웹과 시뮬레이터에서는 정상 동작하지만, 실제 장치에 배포하면 앱이 오류를 내뱉으며 종료됩니다.

 

이러한 문제를 디버깅하는 것은 매우 번거로운 일입니다. stringify와 parse를 통해 값을 확인하는 습관을 들인다면 나중에 문제가 발생해도 빠르게 해결할 수 있습니다.

 

 

4. HTML 렌더링

html 렌더링
HTML 예제

 

애플리케이션에 보여주는 텍스트를 하드코딩 한다면 텍스트를 변경할 때마다 앱에 새롭게 빌드하고 앱 스토어에 다시 제출하는 과정을 거쳐야 합니다.

 

자동 업데이트를 꺼놓은 사용자는 새로운 텍스트를 영영 보지 못할 수도 있습니다. 이를 해결하려면, 절대 변하지 않는 텍스트를 제외하고는 API를 통해 전송해야 합니다.

 

하지만 API를 통해 텍스트를 보내더라도 콘텐츠가 동적으로 변한다면 어떻게 해야 할까요? 또한, 풍부한 사용자 인터랙션이 포함된 기사나 콘텐츠라면 어떻게 해야 할까요? 백엔드에서는 서식 지정이 가능한 텍스트 편집기로 원하는 제목을 입력하고 텍스트 형식을 지정할 수 있지만, 실제 앱에서는 해당 HTML을 네이티브 뷰에 렌더링하는 방법이 필요합니다.

 

이를 위해 HTML을 100% 네이티브 뷰로 렌더링하는 순수 자바스크립트로 구현된 iOS/Android용 리액트 네이티브 컴포넌트인 react-native-render-html을 사용할 수 있습니다.

 

const { width } = useWindowDimensions();
const systemFonts = ['Lato_400Regular'];
return (
 <SafeAreaView style={styles.container}>
   <ScrollView style={styles.scrollView}>
     <RenderHtml
       source={{ html: props.html }}
       systemFonts={systemFonts}
       tagsStyles={tagsStyles}
       contentWidth={width}
     />
   </ScrollView>
 </SafeAreaView>
);

사용 방법은 매우 간단합니다. 또한, 위에서처럼 systemFonts라는 폰트를 삽입할 수 있는 속성이 제공됩니다. tagStyles 속성은 HTML 콘텐츠의 스타일을 지정하는 데 사용할 수 있습니다. 이곳에서 실제로 동작하는 데모를 확인해보세요.

 

 

5. 간단한 조건식 (&&)

제가 리액트를 처음 사용할 무렵 자주 저질렀던 실수 중 하나는 컴포넌트를 렌더링할 때 && 연산자를 과도하게 사용했던 것입니다.

 

{isFetching && <Loading />}

 

그리고 아래와 같이 부울(Boolean)이 아닌 값을 첫 번째 피연산자로 사용하기 전까지는 문제없이 동작했습니다.

 

{users.length && <User />}

 

일반적인 리액트에서 훌륭하게 작동했고 프로젝트의 웹 뷰에서 아무 문제를 일으키지 않았습니다. 심지어 안드로이드와 iOS용 에뮬레이터에서도 정상 동작했습니다. 그러나 실제 기기에 배포하면 이와 같은 로직을 가진 코드 때문에 앱에서 오류가 발생했습니다.

 

Error: Text strings must be rendered within a <Text> component.

 

users 배열이 0보다 크다면 리액트 네이티브는 숫자 형식으로 렌더링하려 시도하지만 실제로는 <Text>컴포넌트이기 때문에 앱이 중단되게 됩니다. 따라서, 논리 연산자 &&를 사용하여 조건식 구문을 간소화하고자 할 때 문자열이 아닌 값이라면 신중하게 사용해야 합니다.

 

리액트 네이티브 커뮤니티는 꾸준히 성장하고 있으며 여러분의 개발을 도와줄 좋은 패키지가 많이 있습니다. 그러나 아직 자바스크립트의 명성을 따라잡기에는 갈 길이 먼 것도 사실입니다. 여기에 공유한 팁을 리액트 네이티브 개발자들이 직접 사용해보고 그동안 겪어왔던 어려움을 극복하는 데 조금이나마 도움이 되기를 바랍니다.


[1] 애플이 iOS, Mac, Apple TV 그리고 Apple Watch 앱 개발용으로 만든 강력하고 직관적인 프로그래밍 언어.
[2] 2013년 드리프티의 맥스 린치, 벤 스페리가 개발한 하이브리드 모바일 앱 제작을 위한 오픈소스 SDK.
[3] 페이스북이 개발한 오픈 소스 모바일 애플리케이션 프레임워크. 자바스크립트로 하나로 주요 모바일 플랫폼에서 동작하는 네이티브 앱을 개발할 수 있다.
[4] OAuth 2.0에서 인증에 사용하는 보안 토큰으로서 API를 통한 자원 요청시 요구된다.

 

<원문>

5 Tips to Solve Common Pitfalls With React Native

 

위 번역글의 원 저작권은 Dan Neciu에게 있으며, 요즘IT는 해당 글로 수익을 창출하지 않습니다.

좋아요

댓글

공유

공유

댓글 0
작가
390
명 알림 받는 중

작가 홈

작가
390
명 알림 받는 중
요즘 해외 개발자들은 어떻게 일할까요? 기획자나 디자이너는요? 그래서 준비했습니다. 읽어볼만한 해외 소식들을 번역해 전합니다. We are the world.
같은 분야를 다룬 콘텐츠
인기 있는 콘텐츠

좋아요

댓글

스크랩

공유

공유

지금 회원가입하고,
요즘IT가 PICK한 뉴스레터를 받아보세요!

회원가입하기
요즘IT의 멤버가 되어주세요! 요즘IT의 멤버가 되어주세요!
요즘IT의 멤버가 되어주세요!
모든 콘텐츠를 편하게 보고 스크랩할 수 있어요.
모든 콘텐츠를 편하게 보고 스크랩 하기
매주 PICK한 콘텐츠를 뉴스레터로 받을 수 있어요.
매주 PICK한 콘텐츠를 뉴스레터로 받기
로그인하고 무료로 사용하기