당신은 두 가지 상황 중 하나에 도달했을 것입니다.
화면이 평평하고 미완성이며, 실제 제품처럼 보이게 하려면 배경이나 버튼을 추가하고 싶을 것입니다. 또는 이미 React Native의 그라디언트를 추가하려고 시도했지만, 현재는 환경 설정에 갇혀 있습니다. 왜냐하면 대부분의 예제는 Expo를 사용하는 반면 다른 예제는 네이티브 프로젝트를 가정하기 때문입니다.
대부분의 튜토리얼은 환경 선택에 중점을 두지 않습니다. API 컴포넌트는 간단합니다. 환경 선택은 그렇지 않습니다. React Native의 선형 그라디언트 설정은 환경에 의존하지 않습니다. colors Expo workflow와 native linking, pods, test mocks 등에 대한 정보를 더 알고 싶으시다면?
목차
- 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 component code
It adds depth, creates separation between sections, and gives high-priority elements a clear visual weight. A good gradient background can make a login screen feel intentional. A good gradient button can make the primary action obvious without resorting to heavy shadows or overly loud borders. By2019년, expo-linear-gradient와 react-native-linear-gradient는 React Native 프로젝트의 42% 이상에 나타났다. ,.
which is a strong signal that gradients aren’t a niche effect anymore. They’re standard UI tooling in production apps, not decoration bolted on at the end, as noted in
- this React Native gradient adoption write-up What gradients do well
- Create depth: A screen with one flat background often looks unfinished. A subtle top-to-bottom blend makes the surface feel layered. 기본 CTAs, 온보딩 카드 및 헤로 헤더는 시각적 노이즈를 추가하지 않고 눈에 띄게 됩니다.
- 이미지 자산을 대체하십시오: 경험이 풍부한 경우, 그라디언트는 추가 배경 이미지를 배송하지 않고도 고급스러움을 제공합니다.
실용적인 규칙: 그라디언트를 사용하여 계층 구조가 중요한 경우. 배경, 헤로 카드, CTA 표면 및 미디어 오버레이가 가장 유익합니다. 양식 필드, 밀도 있는 목록 및 본문 복사본 컨테이너는 일반적으로 그렇지 않습니다.
또한 제품 디자인 관점에서 볼 수 있습니다. 플랫폼을跨越하는 팀이 이미 인터페이스를 일관되게 유지하기 위해 시간을 투자하고 있습니다. 만약 그것이 당신의 스택에 포함되어 있다면, 이 모바일 앱의 UI 및 UX에 대한 다양한 플랫폼을跨越하는 팀이 이미 인터페이스를 일관되게 유지하기 위해 시간을 투자하고 있습니다. 만약 그것이 당신의 스택에 포함되어 있다면, 이
모바일 앱의 UI 및 UX에 대한
This is the fork that causes most of the pain. The rendering API feels almost identical in both libraries, but setup isn’t.
라인업이 잘 맞습니다. 자산이 적고 재사용 가능한 표면이 많으며 화면을跨越하는 시각 시스템이 유지됩니다. expo-linear-gradient선택하는 길: Expo vs Bare React Native Setup입니다. 이 fork가 가장 많은 고통을 주는 것입니다. 렌더링 __CAPGO_KEEP_0__이 두 라이브러리 모두에서 거의 동일한 느낌을 주지만, 설정은 아닙니다. Expo가 관리하는 앱에 있다면 사용하십시오. 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는 네이티브 모듈에 직접 접근할 수 있지만, 네이티브 에지의 문제를 해결해야 합니다.
이 패키지를 설치하세요:
Expo는 빠른 설정, 정상적인 기본값, 그리고 네이티브 에지의 수가 적은 것을 원할 때 올바른 선택입니다.
npm install react-native-linear-gradient
iOS에서 pods를 설치하세요:
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 설정에서 네이티브 모듈 오류와 관련이 있습니다., Stack Overflow 토론 요약에 따르면 네이티브 모듈 오류와 관련된 Stack Overflow 포럼의 68%는 bare React Native 설정에서 네이티브 모듈 오류와 관련이 있습니다.Jest를 bare 앱에서 사용하는 경우 mock을 명시적으로 추가하세요:
Jest 설정에서 이 설정 파일을 참조하세요:
// jest.setup.js
import mockRNLinearGradient from 'react-native-linear-gradient/jest/linear-gradient-mock';
jest.mock('react-native-linear-gradient', () => mockRNLinearGradient);
Gradient는 bare React Native에서 잘 작동하지만, 불완전한 설정을 용납하지 않습니다. 대부분의 오류는 시각적 버그가 아니라 링크, pods, 또는 테스트 환경 문제입니다.
module.exports = {
preset: 'react-native',
setupFiles: ['<rootDir>/jest.setup.js'],
};
실제적인 결정 표:
프로젝트 유형
| __CAPGO_KEEP_0__ | 라이브러리 | 최적의 선택 |
|---|---|---|
| Expo가 관리하는 앱 | expo-linear-gradient |
가장 빠른 경로, 가장 적은 설정 |
| bare React Native 앱 | react-native-linear-gradient |
전체적인 네이티브 제어 |
| bare 앱에 Jest + mock | react-native-linear-gradient __CAPGO_KEEP_0__ |
테스트의 안정성을 유지하기 위해 필요 |
UI 요소의 그라디언트 기술
일반적인 접근 방식은 동일한 작은 그라디언트 패턴 세트를 반복적으로 사용하는 것입니다. 배경. 버튼. 헤드라인. 만약 그 세 가지가 solid라면, 그것들을 여러 화면에서 재사용할 수 있습니다.

A useful mental model is this:
colors색상 팔레트를 제어합니다.start그리고end제어 방향locations전환의 위치를 제어합니다.
스플래시 또는 온보딩 화면이 그라디언트를 사용한다면, 이에 대한 더 자세한 설명은 이 리액트 네이티브 스플래시 화면 가이드 .
전체 화면 배경 그라디언트
이것은 가장 단순하고 재사용 가능한 패턴입니다.
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',
},
});
버튼의 경우 수평 그래디언트가 대각선 그래디언트보다 더 읽기 좋습니다. 레이블을 안정적으로 유지하고 컨트롤이 기울어 보이지 않도록 합니다.
마스크를 사용한 그래디언트 텍스트
이 패턴은 가장 화려한 패턴 중 하나이며, 제한된 범위에서만 유용합니다. 영웅 제목, 업그레이드 배너, 빈 상태 헤드라인은 좋은 후보입니다. 단락 텍스트는 아닙니다.
필요한 것은 @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한 느낌의 로더
가장 간단하고 신뢰할 수 있는 버전은 react-native-reanimated 클리핑된 플레이스 홀더 위에서 gradient 밴드를 왼쪽에서 오른쪽으로 움직이는 애니메이션입니다.
Reanimated이 앱에 이미 설치되어 있지 않다면 설치하고 wrapper를 생성하세요. 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입니다.
애니메이션 컴포넌트
구현에 대한 몇 가지 주의 사항이 있습니다:
- 클리핑을 사용하세요: 부모가 필요합니다,
overflow: 'hidden'둥근 모서리가 있는 경우 스크림이 밖으로 흘러나가지 않도록 하세요. - 밴드가 좁게 유지하세요: 작은 애니메이션 레이어가 전체 표면을 애니메이션하는 것보다 쉽게 조정됩니다.
- 스크린 색상과 일치하세요: 스켈레톤 로더는 주변 레이아웃과 일치해야 하며, 별도의 위젯처럼 보이지 않아야 합니다.
애니메이션 그라디언트는 사용자가 그들을 거의 인지하지 못할 때 가장 잘 작동합니다. 스크림이 화면에서 가장 큰 소리로 들리면, 너무 많은 일을 하고 있습니다.
성능, 접근성 및 플랫폼 특이성
그라디언트가 데모 화면에서 프로덕션으로 이동하면 우려가 달라집니다. code은 여전히 간단하게 보이지만 렌더링 동작, 읽기 가능성 및 플랫폼 일관성은 초기 효과보다 더 중요해집니다.
응용 프로그램의 반응성을 더 광범위하게 개선하고 있다면 모바일 앱 성능 최적화 가이드 같은 마음가짐을 가진다: 불필요한 작업을 줄이고, 실제 장치에서 측정하고, 사용자가 가장 많이 보는 표면을 최적화한다.
성능 체크리스트
자연적인 기울기 효과는 일반적으로 효율적이지만 여전히 잘못 사용할 수 있다.
- 대형 장식 이미지를 대신하는 기울기 효과를 선호한다: 그것들은 일반적으로 더 깨끗하게 전송되고 여러 화면 크기에 쉽게 적응할 수 있다.
- 많은 풀 스크린 레이어를 쌓지 않는다: 한 개의 배경 기울기 효과는 괜찮다. 여러 개의 겹쳐진 투명 기울기 효과에 블러 효과와 무거운 애니메이션을 추가하면 비용이 많이 들 수 있다.
- 재사용 가능한 컴포넌트를 캐시한다: 기울기 카드를 목록에 사용할 때, props를 안정적으로 유지하고 관련된 부모 상태로 인해 다시 렌더링하지 않는다.
좋은 규칙은 기울기를 구조화하는 것이고, 과도한 것은 아니다. 표면을 정의하기 위해 사용하고, 밀집된 피드의 모든 행에 사용하지 않는다.
접근성 체크리스트
색상 경계가 표면 전체에 걸쳐 변할 때, 그라디언트는 읽기 성능을 급격하게 떨어뜨릴 수 있다.
- 가장 밝은 영역에 테스트하라: 만약 흰색 텍스트가 블렌드의 어두운 쪽에서만 작동한다면, 작동하지 않는다.
- 필요할 때 스크림을 추가하라: 배경과 텍스트 사이에 약간 어두운 오버레이를 사용하는 것이 전체 색상 팔레트를 바꾸는 것보다 좋다.
- 대형 디스플레이 텍스트에만 그라디언트를 사용하라: 헤드라인에서는 좋지만, 작은 레이블, 도움말 텍스트, 또는 작업을 완료하는 데 중요한 내용은 아니지만, 그라디언트는 나쁜 선택이다.
그라디언트의 가장 나쁜 경우를 확인하라, 가장 예쁜 경우가 아니다.
플랫폼 특이점 체크리스트
iOS와 Android는 일반적으로 동일한 그라디언트를 렌더링하지만, 항상 완벽하게 렌더링되지 않는다.
| 이슈 | 일반적으로 도움이 되는 것은 다음과 같다. |
|---|---|
| 플랫폼 간 색상 gradient가 다르게 보입니다. | 색상이 적게 사용하고 gradient의 stop 간 명확한 contrast를 사용하세요. |
| 라운드 코너가 gradient를 클립하지 않습니다. | Put overflow: 'hidden' 컨테이너에 |
| gradient가 보이지 않습니다. | 너비, 높이 또는 flex: 1 첫 번째 |
또한 notch가 있는 기기의 status bar 및 safe area 처리를 확인하세요. 시뮬레이터에서 균형 잡힌 gradient가 기기에 느껴질 수 있습니다. content와 background가 notch에 대한 추가 공간을 고려하지 않으면.
문제 해결 및 최종 최적화 방법
프로젝트 노트에 남길 짧은 버전입니다.
- 라이브러리를 워크플로우에 맞춰주세요:
expo-linear-gradientExpo 관리 앱에 대해react-native-linear-gradientbare React Native에 대해 - __CAPGO_KEEP_0__을 의도적으로 유지하기 배경, CTAs, 오버레이 및 헤로 텍스트는 강력한 사용 사례입니다.
- __CAPGO_KEEP_0__을 의도적으로 제어하기 버튼에는 수평, 장식 배경에는 대각선, 큰 텍스트에는 마스킹만 사용합니다.
- 빈 상태 대신 콘텐츠를 위한 디자인하기 실제 복사본, 아이콘 및 상태栏 처리와 함께 테스트하기
- bare 설정을 native 설정으로 다루기 Pods, 링크 및 Jest 모의는 선택 사항이 아닙니다.
반복적으로 나타나는 세 가지 일반적인 실패
그라디언트가 나타나지 않음
원인: 컴포넌트가 보이지 않는 크기를 가지고 있기 때문입니다.
해결: 명시적인 높이 또는 부모 요소의 크기를 주거나, 레이아웃 박스를 가지고 있는 부모 요소를 주세요. gradient에 레이아웃 박스가 없으면 의미 있는 방식으로 렌더링되지 않습니다. flex: 1iOS 빌드가 설치 후에 깨지기 시작합니다.
원인: pods가 설치되지 않았거나 네이티브 의존성 그래프가 동기화되지 않았기 때문입니다.
해결:
빌드 폴더를 정리할 필요가 있으면서도, pod install 빌드 폴더를 정리한 후 앱을 다시 빌드하세요. bare 프로젝트의 경우, 패키지 설치만으로는 충분하지 않습니다. ios테스트가 네이티브 모듈 오류로 실패합니다.
원인: Jest가 실제 네이티브 모듈을 로드하고 있기 때문입니다.
해결:
네이티브 모듈을 모킹하세요. react-native-linear-gradient __CAPGO_KEEP_0__ react-native-linear-gradient/jest/linear-gradient-mock __CAPGO_KEEP_0__
이 가이드의 모든 내용에서 하나만 기억하세요: 그라디언트 자체는 쉽습니다. 실제로 사용할 수 있는 설정은 주된 노력입니다. 앱 아키텍처에 적합한 라이브러리를 선택하면 그 이후의 모든 과정이 훨씬 더 예측 가능해집니다.
팀이 하이브리드 모바일 앱을 배포하고 스토어 리뷰를 기다리지 않고 JavaScript, CSS, 복사본, 설정, 및 자산 업데이트 push하고 싶다면 Capgo CapacitorJS 및 Electron 팀에 대한 제어된 라이브 업데이트, 롤아웃 채널, 롤백 보호, 및 릴리스 시각화를 제공합니다. 배포 프로세스를 블랙박스로 만들지 않습니다.