당신은 두 가지 상황 중 하나에 부딪혔을 것이다.
화면이 평평하고 미완성이며, 실제 제품처럼 보이게 하려면 배경이나 버튼을 추가하고 싶을 것이다. 또는 이미 React Native 그라디언트를 추가하려고 시도했지만, 현재는 환경 설정에 갇혀 있다. 왜냐하면 대부분의 예제는 Expo를 사용하는 반면 다른 예제는 네이티브 프로젝트를 사용한다.
대부분의 튜토리얼은 환경 선택에 중단된다. 컴포넌트 API은 간단하다. 환경 선택은 아니다. React Native에서 선형 그라디언트를 설정하는 것은 환경에 의존하지 않는다. colors 속성과 더 많은 정보는 Expo 관리 워크플로우에서 사용 중인지 또는 네이티브 링크, pods, 테스트 모킹과 직접 다루는지에 따라 결정됩니다.
목차
- React Native 앱이 왜 그라디언트를 필요로 하는가
- Expo vs Bare React Native 설정에서 선택하는 방법
- UI 요소에 대한 핵심 그라디언트 기법
- __CAPGO_KEEP_0__
- __CAPGO_KEEP_3__
- __CAPGO_KEEP_7__
__CAPGO_KEEP_11__
모바일 UI가 많은 이유는 동일합니다. 레이아웃은 괜찮고, 간격은 괜찮고, 타이포그래피는 적절하지만 화면은 여전히 죽어 보입니다. Solid fills로 모든 것을 채우면 placeholder처럼 보이기 때문에 시각 시스템이 많은 일을 해야 합니다.
A linear gradient React Native 컴포넌트가 code으로 매우 적은 양의 작업을 통해 해결합니다. 이 기능은 깊이를 더해 섹션 간의 구분을 만들고, 중요 요소에 명확한 시각적 가중치를 부여합니다. 좋은 그레이디언트 배경은 로그인 화면을 의도적으로 느끼게 만들 수 있습니다. 좋은 그레이디언트 버튼은 중요한 액션을 명확하게 나타내며, 무거운 그림자나 너무 큰 테두리를 사용하지 않고도 이를 달성할 수 있습니다.
By 2019년 expo-linear-gradient와 react-native-linear-gradient는 React Native 프로젝트의 42% 이상에 나타났습니다., 이는 gradient가 더 이상 특수한 효과가 아니라는 강력한 신호입니다. 그들은 프로덕션 앱에서 표준 UI 도구로 사용되고 있으며, 끝에 덧붙여지는 장식이 아닌, noted in 에서 언급한 것처럼. 이 React Native 그라디언트 도입 글.
__CAPGO_KEEP_0__이 잘 나타나는 색상 gradient는 무엇이 잘 작동하는지
- 깊이 생성: __CAPGO_KEEP_0__ 화면에 단조로운 배경이 있는 경우 종종 불완전한 느낌을 주지만, 상하로 약간의 블렌딩을 적용하면 표면이 층층이 보이는 느낌을 줄 수 있습니다.
- Guide attention: Primary CTAs, onboarding cards, and hero headers stand out without adding visual noise.
- 이미지 자산을 교체하십시오. 다양한 경우, gradient는 추가 배경 이미지를 배송하지 않고도 polish를 제공합니다.
실용적인 규칙: 위계가 중요한 경우 gradient를 사용하십시오. 배경, hero cards, CTA 표면, 미디어 오버레이가 가장 유리합니다. 양식 field, 밀도 있는 목록, 본문 복사본 컨테이너는 일반적으로 그렇지 않습니다.
이러한 cross-platform UI and UX practices for mobile apps 는 동일한 사고와 일치합니다: 더 적은 자산, 더 재사용 가능한 표면, 화면을 가로지르는 시각 시스템이 유지됩니다.
Expo vs Bare React Native Setup
이것이 가장 많은 고통을 주는 분기입니다. 렌더링 API은 두 라이브러리 모두에서 거의 동일한 느낌을 주지만, 설정은 아닙니다.
Expo 관리 앱에서 사용하는 경우 expo-linear-gradient를 사용하십시오. Bare React Native 앱에서 사용하는 경우, react-native-linear-gradient. __CAPGO_KEEP_0__의 선을 흐리려는 시도를 하지 마십시오. 그 이유를 정확히 알고 있는 경우에만.

Expo 설정
Expo는 더 편한 경로입니다. 설치는 간단하고, 버전 일치가 처리되며, 네이티브 링크에 대해 생각할 필요가 없습니다.
이런 식으로 설치하세요:
npx expo install expo-linear-gradient
이런 식으로 사용하세요:
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
export default function App() {
return (
<LinearGradient
colors={['#0f172a', '#1d4ed8']}
style={styles.container}
>
<Text style={styles.text}>Hello gradient</Text>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: '#fff',
fontSize: 24,
fontWeight: '700',
},
});
Expo는 빠른 설정, 정상적인 기본 설정, 그리고 네이티브 에지의 수가 적은 것을 원할 때 올바른 선택입니다. 또한 팀이 고급 Expo 워크플로우를 탐색하는 경우, 관리 경로가 앱의 요구를 충족하지 못할 때만 Expo 개발 클라이언트를 사용하여 커스텀 네이티브 기능을 사용합니다. bare React Native 설정
bare React Native는 네이티브 모듈에 직접 접근할 수 있지만,ROUGH EDGE를 관리해야 합니다.
이 패키지를 설치하세요:
Expo는 빠른 설정, 정상적인 기본 설정, 그리고 네이티브 에지의 수가 적은 것을 원할 때 올바른 선택입니다.
npm install react-native-linear-gradient
For iOS, __CAPGO_KEEP_0__ install __CAPGO_KEEP_1__:
cd ios && pod install
기본 사용 방법:
import React from 'react';
import { StyleSheet, Text } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
export default function App() {
return (
<LinearGradient
colors={['#111827', '#7c3aed']}
style={styles.container}
>
<Text style={styles.text}>Hello gradient</Text>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: '#fff',
fontSize: 24,
fontWeight: '700',
},
});
bare 프로젝트에서 일반적으로 발생하는 문제
대부분의 튜토리얼에서 누락된 부분은 테스트 및 네이티브 설정입니다. Stack Overflow 토론 요약에 따르면, 2024년부터 2025년까지 Stack Overflow 주제에 대한 68%의 스레드가 네이티브 모듈 오류로 인해 bare React Native 설정에서 발생합니다.또한 동일한 출처는 Jest 모킹과 iOS CocoaPods 충돌과 같은 반복적인 문제에 대해 언급합니다.
Jest를 사용하는 경우 bare 앱에 mock을 명시적으로 추가하십시오:
// jest.setup.js
import mockRNLinearGradient from 'react-native-linear-gradient/jest/linear-gradient-mock';
jest.mock('react-native-linear-gradient', () => mockRNLinearGradient);
Jest 구성에 설정 파일을 참조하십시오:
module.exports = {
preset: 'react-native',
setupFiles: ['<rootDir>/jest.setup.js'],
};
bare React Native는 그라디언트에 잘 작동합니다. 그러나 완전한 설정이 누락된 경우에는 용서하지 않습니다. 대부분의 실패는 시각적 버그가 아니라 링크, pods, 또는 테스트 환경 문제입니다.
실용적인 결정 표:
| 프로젝트 유형 | 도구 | 최적의 선택 |
|---|---|---|
| Expo가 관리하는 앱 | expo-linear-gradient |
가장 빠른 경로, 가장 적은 설정 |
| Bare React Native 앱 | react-native-linear-gradient |
전체적인 네이티브 제어 |
| Bare 앱에 Jest | react-native-linear-gradient + mock |
테스트를 안정적으로 유지하기 위해 필수 |
UI 요소의 Core Gradient 기법
UI 요소의 Gradient 패턴을 동일한 작은 세트를 반복적으로 사용하는 일반적인 접근 방식입니다. 배경. 버튼. 헤드라인. 이 세 가지가 solid일 경우, 많은 화면에서 재사용할 수 있습니다.

이런 정신 모델이 유용합니다:
colors__CAPGO_KEEP_0__을 제어합니다.start및end제어 방향locations__CAPGO_KEEP_0__이 전환되는 곳을 제어합니다.
스플래시 또는 온보딩 진입 화면이 그라디언트를 사용한다면, 이에 자연스럽게 어울리는 더 광범위한 시작 시퀀스 패턴이 이 React Native 스플래시 화면 가이드.
전체 화면 배경 그라디언트
이것이 가장 단순하고 재사용 가능한 패턴입니다.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
// For bare RN, switch to:
// import LinearGradient from 'react-native-linear-gradient';
export default function WelcomeScreen() {
return (
<LinearGradient
colors={['#0f172a', '#1e293b', '#2563eb']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.container}
>
<View style={styles.content}>
<Text style={styles.title}>Welcome back</Text>
<Text style={styles.subtitle}>Your workspace is ready.</Text>
</View>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 24,
},
title: {
color: '#fff',
fontSize: 32,
fontWeight: '800',
marginBottom: 8,
},
subtitle: {
color: 'rgba(255,255,255,0.8)',
fontSize: 16,
},
});
대각선 블렌드는 기본적인 수직 블렌드보다 더 동적하게 느껴질 때가 많습니다. 그 이유는 start={{ x: 0, y: 0 }} 및 end={{ x: 1, y: 1 }} 화면이 주로 꾸미기 위한 경우에는 좋은 기본값입니다.
독립적으로 색상을 선택하지 마세요. 실제 텍스트, 아이콘, 상태栏 스타일과 함께 테스트하세요. Figma에서 좋은 색상 팔레트는 콘텐츠가 위에 올려진 순간 즉시 실패할 수 있습니다.
그라디언트 버튼이 여전히 버튼처럼 행동하는 경우
이러한 일반적인 실수는 그라디언트에 터치 동작을 직접 넣고 비활성화 상태, 클릭 피드백, 패딩 일관성을 잊는 것입니다. 버튼의 의미를 유지하고 그라디언트를 시각적层로 두세요.
import React from 'react';
import {
Pressable,
StyleSheet,
Text,
ViewStyle,
StyleProp,
} from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
type Props = {
title: string;
onPress: () => void;
disabled?: boolean;
style?: StyleProp<ViewStyle>;
};
export function GradientButton({
title,
onPress,
disabled = false,
style,
}: Props) {
return (
<Pressable onPress={onPress} disabled={disabled} style={style}>
{({ pressed }) => (
<LinearGradient
colors={
disabled
? ['#94a3b8', '#94a3b8']
: pressed
? ['#7c3aed', '#2563eb']
: ['#8b5cf6', '#3b82f6']
}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
style={styles.button}
>
<Text style={styles.label}>{title}</Text>
</LinearGradient>
)}
</Pressable>
);
}
const styles = StyleSheet.create({
button: {
minHeight: 52,
borderRadius: 14,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 20,
},
label: {
color: '#fff',
fontSize: 16,
fontWeight: '700',
},
});
버튼의 경우 수평 그라디언트가 대각선 그라디언트보다 더 읽기 좋습니다. 레이블을 안정시키고 컨트롤이 기울어지지 않도록 합니다.
그라디언트 텍스트에 마스크를 사용하세요
이 패턴은 가장-flashy 패턴입니다. 하지만 제한된 범위에서만 사용하세요. hero 제목, 업그레이드 배너, 빈 상태 헤드라인은 좋은 후보지만, 문단 텍스트는 아닙니다.
필요한 경우 @react-native-masked-view/masked-view.
npm install @react-native-masked-view/masked-view
그라디언트 마스크를 만들려면
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MaskedView from '@react-native-masked-view/masked-view';
import { LinearGradient } from 'expo-linear-gradient';
export default function GradientHeadline() {
return (
<View style={styles.container}>
<MaskedView
maskElement={
<View style={styles.maskWrapper}>
<Text style={styles.title}>Premium analytics</Text>
</View>
}
>
<LinearGradient
colors={['#22c55e', '#06b6d4', '#3b82f6']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
locations={[0, 0.5, 1]}
>
<Text style={[styles.title, styles.hiddenText]}>Premium analytics</Text>
</LinearGradient>
</MaskedView>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 24,
},
maskWrapper: {
backgroundColor: 'transparent',
},
title: {
fontSize: 34,
fontWeight: '800',
letterSpacing: -1,
},
hiddenText: {
opacity: 0,
},
});
locations 색상 중 하나가 다른 색상보다 더 많은 시각적 공간을 차지할 때 가장 중요합니다. 블렌드가 흐릿하다면 색상 수를 줄이세요. 일반적으로 디자인을 더 빠르게 고치게 됩니다.
그라디언트를 애니메이션으로 사용하여 생명력을 부여하세요
정적 그라디언트는 폴리시를 제공합니다. 애니메이션 그라디언트는 피드백을 제공합니다.
가장 실용적인 사용은 화려한 배경이 아닙니다. 그것은 셔머 로더입니다. 이 효과는 앱이 활성화되어 있고 데이터가 들어오고 현재 레이아웃이 의도된 것이 아니라 깨진 것이 아닌지 알려줍니다.

Shimmer 컴포넌트는 다른 동작 패턴과도 잘 어울립니다. 이미 애니메이션 아이콘이나 로더를 사용하는 앱이 있다면, 이 React Native에서 Lottie 사용하는 방법 이 가이드는 gradient shimmer가 충분하고 richer animation asset가 더 의미가 있는지 결정하는 데 유용합니다.
native-feeling의 shimmer 로더
가장 간단하고 신뢰할 수 있는 버전은 react-native-reanimated 클리핑된 플레이스 홀더 위에서 gradient 밴드를 왼쪽에서 오른쪽으로 움직이는 애니메이션입니다.
Reanimated이 앱에 이미 설치되어 있지 않다면 설치하고 wrapper를 생성하세요. 그 안에서 overflow: 'hidden'.안에 gradient layer를 왼쪽에서 오른쪽으로 애니메이션하세요.
import React, { useEffect } from 'react';
import { StyleSheet, View, ViewStyle, StyleProp } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import Animated, {
useAnimatedStyle,
useSharedValue,
withRepeat,
withTiming,
Easing,
} from 'react-native-reanimated';
const AnimatedView = Animated.createAnimatedComponent(View);
type Props = {
width?: number | string;
height?: number;
borderRadius?: number;
style?: StyleProp<ViewStyle>;
};
export function ShimmerPlaceholder({
width = '100%',
height = 16,
borderRadius = 8,
style,
}: Props) {
const translateX = useSharedValue(-220);
useEffect(() => {
translateX.value = withRepeat(
withTiming(220, {
duration: 1200,
easing: Easing.linear,
}),
-1,
false
);
}, [translateX]);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }],
}));
return (
<View
style={[
styles.container,
{ width, height, borderRadius },
style,
]}
>
<AnimatedView style={[styles.shimmer, animatedStyle]}>
<LinearGradient
colors={['rgba(255,255,255,0)', 'rgba(255,255,255,0.35)', 'rgba(255,255,255,0)']}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
style={styles.gradient}
/>
</AnimatedView>
</View>
);
}
const styles = StyleSheet.create({
container: {
overflow: 'hidden',
backgroundColor: '#e5e7eb',
},
shimmer: {
...StyleSheet.absoluteFillObject,
width: 220,
},
gradient: {
flex: 1,
},
});
이것이 작동하는 이유는 gradient 정의 자체를 애니메이션하는 것이 아니라 gradient layer를 정적 플레이스 홀더 위에서 애니메이션하는 것입니다. 그게 더 간단하고 더 쉽게 이해할 수 있고, 일반적으로 장치 간에 더 안정적입니다.
이 효과의 시각적인_walkthrough입니다.
애니메이션 컴포넌트
A few implementation notes matter:
- 클리핑을 사용하세요: 부모가 필요합니다,
overflow: 'hidden'또는 둥근 모서리가 bleed되면 shimmer가 밖으로 나옵니다. - 밴드가 좁게 유지하세요: 작은 애니메이션 레이어는 전체 표면을 애니메이션하는 것보다 쉽게 조정할 수 있습니다.
- 스크린의 기본 색상과 일치하세요: 스켈레톤 로더는 주변 레이아웃과 일치해야 하며 별도의 위젯처럼 보이지 않아야 합니다.
애니메이션 그라디언트는 사용자가 거의 알아차리지 못할 때 가장 잘 작동합니다. 만약 shimmer가 화면에서 가장 큰 소리로 들리면, 너무 많이 하고 있습니다.
성능, 접근성 및 플랫폼 특이성
그라디언트가 데모 화면에서 프로덕션으로 이동하면 우려가 달라집니다. code는 여전히 간단하게 보이지만 렌더링 동작, 읽기 가능성 및 플랫폼 일관성은 초기 효과보다 더 중요해집니다.
응용 프로그램의 반응성을 더 넓게 개선하고 있다면, 모바일 앱 성능 최적화 가이드 같은 마음가짐을 가진다: 불필요한 작업을 줄이고, 실제 기기에서 측정하고, 사용자가 가장 많이 보는 표면을 최적화한다.
성능 체크리스트
네이티브 그라디언트는 일반적으로 효율적이지만 여전히 그들을 잘못 사용할 수 있다.
- 큰 장식 이미지를 대신하는 그라디언트를 선호하라: 그들은 일반적으로 더 깨끗하게 전송되고 여러 화면 크기에 쉽게 적응할 수 있다.
- 많은 풀 스크린 레이어를 쌓지 말라: 한 배경 그라디언트는 괜찮다. 여러 겹의 투명한 그라디언트에 블러와 무거운 애니메이션을 추가하면 비용이 많이 들 수 있다.
- 재사용 가능한 컴포넌트를 메모이제이션하라: 그라디언트 카드를 목록에 사용할 때, props를 안정적으로 유지하고 관련된 부모 상태로 인해 다시 렌더링하지 말라.
좋은 규칙은 그라디언트를 구조적이고 과하지 않게 사용하는 것이다. 표면을 정의하기 위해 그라디언트를 사용하고, 밀집된 피드의 모든 행에 그라디언트를 사용하지 말라.
접근성 체크리스트
색상 경계가 표면 전체에 걸쳐 변할 때, 그라디언트는 읽기 성능을 급격하게 떨어뜨릴 수 있습니다.
- 어두운 영역의 가장 밝은 부분에 테스트 텍스트를 확인하십시오. 그라디언트의 어두운 쪽에서만 흰색 텍스트만이 작동한다면, 작동하지 않습니다.
- 필요할 때 스크림을 추가하십시오. 배경과 텍스트 사이의 약간 어두운 오버레이가 전체 색상 팔레트를 바꾸는 것보다 종종 더 좋습니다.
- 대형 디스플레이 텍스트에만 그라디언트를 사용하십시오. 헤드라인에서는 좋지만, 작은 레이블, 도움말 텍스트, 또는 작업을 완료하는 데 중요한 내용은 아닙니다.
그라디언트에서 가장 나쁜 경우의 점을 확인하십시오, 아니라 가장 예쁜 점을.
플랫폼 특이점 체크리스트
iOS와 Android는 일반적으로 동일한 그라디언트를 렌더링하지만, 항상 완벽하게 렌더링되지 않습니다.
| 이슈 | 일반적으로 도움이 됩니다. |
|---|---|
| 플랫폼 간 색상 gradient가 다르게 보인다 | 색상이 적고 gradient 중간의 contrast가 명확한 gradient를 사용하라 |
| 라운드 코너가 gradient를 클립하지 않는다 | container에 overflow: 'hidden' gradient가 보이지 않는다 |
| width, height, 또는 | 첫 번째 flex: 1 status bar와 safe area 처리를 확인하라. 시뮬레이터에서 balance가 되는 gradient가 notch가 있는 기기에선 top-heavy로 느껴질 수 있다. content와 background가 notch를 고려하지 않으면서 gradient를 사용할 때는 주의하라. |
문제 해결 및 최종 최적화
프로젝트 노트에 남길 짧은 버전이다.
라이브러리를 워크플로에 맞춰라:
- 라이브러리와 워크플로를 맞추라
expo-linear-gradientExpo 관리 앱에 대해react-native-linear-gradientbare React Native에 대해 - 그라디언트를 의도적으로 사용하십시오: 배경, CTAs, 오버레이, 및 헤로 텍스트는 강력한 사용 사례입니다.
- 방향을 의도적으로 제어하십시오: 버튼에는 수평, 장식 배경에는 대각선, 큰 텍스트에만 마스킹을 사용하십시오.
- 빈 상태 대신 콘텐츠를 위한 디자인하십시오: 실제 복사본, 아이콘, 및 상태바 처리와 함께 테스트하십시오.
- bare 설정을 native 설정으로 다루십시오: Pods, 링크, 및 Jest 모의는 선택 사항이 아닙니다.
반복적으로 나타나는 세 가지 일반적인 실패가 있습니다.
그라디언트가 나타나지 않음
원인: 컴포넌트가 보이지 않는 크기를 가지고 있기 때문입니다.
해결: 명시적인 높이 또는 부모 요소의 크기를 주거나, 레이아웃 박스를 가지고 있는 부모 요소를 주세요. gradient에 레이아웃 박스가 없으면 의미 있는 방식으로 렌더링되지 않습니다. flex: 1iOS 빌드가 설치 후에 깨지기 시작합니다.
원인: pods가 설치되지 않았거나 네이티브 의존성 그래프가 동기화되지 않았기 때문입니다.
해결:
를 실행하세요. pod install 필요한 경우 빌드 폴더를 정리한 후 앱을 다시 빌드하세요. bare 프로젝트의 경우 패키지 설치만으로는 충분하지 않습니다. ios테스트가 네이티브 모듈 오류로 실패합니다.
원인: Jest가 실제 네이티브 모듈을 로드하고 있기 때문입니다.
해결:
를 mock하세요. react-native-linear-gradient __CAPGO_KEEP_0__ react-native-linear-gradient/jest/linear-gradient-mock __CAPGO_KEEP_0__
이 가이드에서 하나만 기억하세요: 그레이디언트 자체는 쉽습니다. 실제 배포 준비가 가장 큰 노력입니다. 앱 아키텍처에 적합한 라이브러리를 선택하면 그 이후의 모든 것이 훨씬 더 예측 가능해집니다.
팀이 하이브리드 모바일 앱을 배포하고 스토어 리뷰를 기다리지 않고 자바스크립트, CSS, 복사본, 구성, 및 자산 업데이트 push하고 싶다면 Capgo 이것은 CapacitorJS 및 Electron 팀에 제어된 라이브 업데이트, 롤아웃 채널, 롤백 보호, 및 릴리스 시각성을 제공합니다. 배포 프로세스를 블랙박스로 만들지 않습니다.