
리액트 네이티브에서 <Button> 컴포넌트는 직접적으로 style 속성을 지원하지 않기 때문에, 스타일을 적용하려면 <Button> 대신 다른 컴포넌트(예: <TouchableOpacity> 또는 <Pressable>)를 사용하거나, Button 외부에 스타일이 적용된 래퍼(View)를 만들어야 합니다.
<Button>, <TouchableOpacity>, <Pressable>은 모두 터치 가능한 요소를 구현하기 위한 컴포넌트지만, 기능과 스타일링에 차이가 있습니다.
| 컴포넌트 | 특징 | 스타일링 | 사용 시기 |
|---|---|---|---|
<Button> | 기본적인 터치 가능한 버튼 | title, onPress 등 제한적 속성만 제공. 커스터마이즈 어려움 | 빠르게 간단한 버튼을 추가할 때 |
<TouchableOpacity> | 터치 시 투명도가 변하는 "눌리는" 효과 | style 속성으로 유연한 스타일링 가능. 텍스트, 이미지 등과 조합 가능 | 커스텀 디자인이 필요하거나, 이미지를 포함할 때 |
<Pressable> | onPressIn, onPressOut, onLongPress 등 세밀한 터치 이벤트 제어 | 유연한 스타일링 + pressed 상태에 따른 동적 스타일 적용 가능 | 복잡한 터치 상호작용이나 상태별 스타일 변경이 필요할 때 |
버튼의 외관과 동작을 세밀하게 제어하고 싶다면
<TouchableOpacity>나<Pressable>을 사용하는 것이 좋습니다.
최소 너비 기반 크기 결정 — flex:1이 있어도 콘텐츠(placeholder/텍스트) 길이를 기준으로 자체 최소 너비를 가진다.
flex-row + flex-wrap 환경에서는 가로만 확장 — 세로 높이는 intrinsic height 그대로 유지되고, 가로는 남은 공간만큼 확장되지만 부모 높이를 채우지 않는다. (flex: 1이어도)
자동 줄바꿈 — 다른 컴포넌트들과 flex-wrap, flex-row를 가진 View에 있을 시, 남은 가로 공간이 최소 너비보다 작아지면 자동 줄바꿈. minWidth를 지정하면 줄바꿈 시점을 조절할 수 있음.
includeFontPadding 영향 — Android는 includeFontPadding 영향으로 기본 높이가 더 커질 수 있다. 아래 코드로 기본 패딩을 제거:
style={{
paddingVertical: 0,
paddingTop: 0,
paddingBottom: 0,
includeFontPadding: false,
}}
npm:react-native-svg-transformer
TypeScript를 사용한다면 declaration.d.ts에 아래를 추가하여 모듈을 any 타입으로 인식하게 한다:
declare module 'react-native-indicators';
25.10.30 수정 — New Architecture 도입 이후 BoxShadow 스타일을 적용할 수 있게 되었다.
https://leerowoon.dev/posts/react-native-shadow-style
리액트 네이티브에서 그림자는 플랫폼에 따라 다르게 적용됩니다.
iOS — shadowColor, shadowOffset, shadowOpacity, shadowRadius 사용:
<View style={{
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.8,
shadowRadius: 3,
}}>
Android — elevation 사용:
<View style={{
elevation: 5,
}}>
플랫폼별 분기 적용:
import { View, Platform } from 'react-native';
const MyComponent = () => {
return (
<View style={{
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.8,
shadowRadius: 3,
},
android: {
elevation: 5,
},
})
}}>
{/* Your content here */}
</View>
);
};
웹에서와 달리, style이 아닌 라이브러리 컴포넌트를 사용해야 한다.
공식문서
설치:
npx expo install expo-location
사용 예시 — 스크린이 열릴 때 위도/경도를 화면에 표시:
import React, { useState, useEffect } from "react";
import { View, Text } from "react-native";
import * as Location from "expo-location";
const LocationScreen = () => {
const [location, setLocation] = useState(null);
const [errorMsg, setErrorMsg] = useState(null);
useEffect(() => {
(async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") {
setErrorMsg("Permission to access location was denied");
return;
}
let loc = await Location.getCurrentPositionAsync({});
setLocation(loc);
})();
}, []);
let text = "Waiting..";
if (errorMsg) {
text = errorMsg;
} else if (location) {
text = `Latitude: ${location.coords.latitude}, Longitude: ${location.coords.longitude}`;
}
return (
<View>
<Text>{text}</Text>
</View>
);
};
export default LocationScreen;
이미지를 HTTP 통신으로 백엔드 서버에 보낼 때 TypeError: Network request failed 에러가 발생할 수 있다.
레퍼런스
해결법 — 이미지를 blob 형태로 FormData에 담아 전송:
const formData = new FormData();
imgs.forEach((img, index) => {
formData.append("photos", {
uri: imgs[index],
type: "image/jpeg",
name: `photo${index}.jpg`,
});
});
react-native-safe-area-context를 설치해 사용한다. 블로그
import {SafeAreaView} from 'react-native'— iOS만 지원
import {SafeAreaView} from 'react-native-safe-area-context'— Android도 지원
스플래시 돌아가는 동안 로딩 처리를 하면 좋다.
글로 작성
Fastlane 설정 ~ 내부테스트/TestFlight 배포까지
파라미터 AOS
파라미터 IOS