Probabilmente ti sei trovato in una di queste due situazioni.
O la tua schermata sembra piatta e incompleta, e vuoi un background o un bottone che sembri un prodotto reale invece di uno scaffold. Oppure hai già provato ad aggiungere un gradiente in React Native, ma ora sei bloccato nel setup perché metà degli esempi usa Expo e l'altra metà assume un progetto bare native.
È proprio in questo bivio che la maggior parte dei tutorial smette di essere utile. Il componente API è semplice. La scelta dell'ambiente no. Un setup pulito di linear gradient in React Native dipende meno dalla colors prop e altro, sia che tu stia usando il workflow gestito di Expo, sia che tu debba gestire direttamente native linking, pods e test mock.
Indice dei contenuti
- Perché la tua app React Native ha bisogno dei gradienti
- Scegliere la strada: Expo vs Bare React Native
- Tecniche core per gradienti negli elementi UI
- Animare i gradienti per renderli vivi
- Performance, accessibilità e quirk delle piattaforme
- Troubleshooting e Best Practice finali
Perché la tua app React Native ha bisogno dei gradienti
Molte UI mobile falliscono per lo stesso motivo. Il layout è ok, lo spacing è ok, la tipografia è accettabile, ma lo schermo sembra comunque piatto. I colori pieni fanno sembrare tutto un placeholder, a meno che il resto del sistema visivo non sia molto complesso.
Un linear gradient in React Native component lo risolve con pochissimo code. Aggiunge profondità, crea separazione tra le sezioni e dà peso visivo agli elementi prioritari. Un buon gradiente di sfondo può rendere una schermata di login curata. Un buon bottone con gradiente può rendere chiara l'azione principale senza ricorrere a ombre pesanti o bordi troppo vistosi.
Nel 2019, expo-linear-gradient e react-native-linear-gradient erano presenti in oltre il 42% dei progetti React Native, un segnale chiaro che i gradienti non sono più un effetto di nicchia. Sono strumenti UI standard nelle app in produzione, non semplici decorazioni aggiunte alla fine, come evidenziato in questo articolo sull'adozione dei gradienti in React Native.
I vantaggi dei gradienti
- Creare profondità: Uno schermo con uno sfondo piatto spesso sembra incompleto. Una sfumatura sottile dall'alto verso il basso conferisce profondità alla superficie.
- Guidare l'attenzione: CTA primarie, card di onboarding e hero header risaltano senza aggiungere rumore visivo.
- Sostituire le immagini: In molti casi, un gradiente offre un look rifinito senza dover includere immagini di sfondo extra.
Regola pratica: Usa i gradienti dove la gerarchia è importante. Sfondi, hero card, superfici CTA e overlay multimediali ne traggono maggior beneficio. Campi di input, liste dense e contenitori di testo solitamente no.
C'è anche un aspetto legato al product design. I team che lavorano su più piattaforme cercano già di mantenere le interfacce coerenti. Se questo fa parte del tuo stack, queste pratiche UI e UX cross-platform per app mobile si allineano allo stesso approccio: meno asset, più superfici riutilizzabili e sistemi visivi che funzionano su ogni schermo.
Scegliere la strada: Expo vs Bare React Native
Questo è il bivio che crea più problemi. Il rendering API sembra quasi identico in entrambe le librerie, ma il setup no.
Se usi un'app gestita con Expo, usa expo-linear-gradient. Se usi un'app bare React Native, usa react-native-linear-gradient. Non cercare di sfumare questi confini a meno che tu non sappia esattamente perché lo stai facendo.

Setup Expo
Expo è la strada più semplice. L'installazione è diretta, il version matching è gestito automaticamente e non devi preoccuparti del native linking.
Installalo così:
npx expo install expo-linear-gradient
Ecco come usarlo:
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 è la scelta giusta se cerchi un setup rapido, impostazioni predefinite sensate e meno complicazioni native. È anche per questo che i team che esplorano workflow Expo avanzati spesso confrontano Capgo ed Expo EAS per i live updates quando il percorso managed non è più sufficiente per le esigenze dell'app.
Setup Bare React Native
React Native "bare" ti offre l'accesso diretto ai moduli nativi, ma dovrai gestire tu le complessità.
Installa il pacchetto:
npm install react-native-linear-gradient
Per iOS, installa i pod:
cd ios && pod install
Utilizzo base:
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',
},
});
Dove i progetti bare di solito falliscono
L'elemento mancante nella maggior parte dei tutorial è il testing e il setup nativo. Secondo il riassunto di questa discussione su Stack Overflow, Il 68% dei thread su Stack Overflow su questo tema tra il 2024 e il 2025 riguarda errori dei moduli nativi in setup React Native bare, e la stessa fonte segnala problemi ricorrenti con il mocking di Jest e conflitti CocoaPods su iOS.
Se usi Jest in un'app bare, aggiungi esplicitamente il mock:
// jest.setup.js
import mockRNLinearGradient from 'react-native-linear-gradient/jest/linear-gradient-mock';
jest.mock('react-native-linear-gradient', () => mockRNLinearGradient);
E referenzia quel file di setup nella tua configurazione di Jest:
module.exports = {
preset: 'react-native',
setupFiles: ['<rootDir>/jest.setup.js'],
};
React Native bare funziona bene con i gradienti. Solo che non perdona un setup incompleto. Quasi tutti i problemi non sono bug visivi, ma problemi di linking, pods o ambiente di test.
Ecco la tabella decisionale pratica:
| Tipo di progetto | Libreria | Miglior scelta |
|---|---|---|
| App gestita con Expo | expo-linear-gradient |
Percorso più veloce, setup minimo |
| App React Native Bare | react-native-linear-gradient |
Controllo nativo completo |
| App Bare con Jest | react-native-linear-gradient + mock |
Necessario per test stabili |
Tecniche Gradient Core per UI
Un approccio comune è usare lo stesso set di pattern gradient. Sfondi, bottoni, titoli. Se questi tre sono solidi, puoi riutilizzarli in molte schermate.

Un modello mentale utile è questo:
colorscontrolla la palettestarteendcontrolla la direzionelocationscontrolla dove avvengono le transizioni
Se la splash screen o la schermata di onboarding usano un gradiente, si integrano naturalmente con i pattern di startup descritti in questa guida alla splash screen per React Native.
Gradient a tutto schermo
Questo è il pattern più semplice e riutilizzabile.
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,
},
});
Una sfumatura diagonale risulta solitamente più dinamica di una verticale standard. Ecco perché start={{ x: 0, y: 0 }} e end={{ x: 1, y: 1 }} sono un'ottima scelta predefinita quando la schermata è principalmente decorativa.
Non scegliere i colori isolatamente. Testali con testo, icone e stili della status bar reali. Una palette perfetta su Figma può fallire non appena ci sovrapponi il contenuto.
Bottoni con gradiente che si comportano come veri bottoni
L'errore comune è applicare il touch direttamente al gradiente, dimenticando lo stato disabled, il feedback al press o la coerenza del padding. Mantieni il bottone semantico e usa il gradiente solo come layer visivo.
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',
},
});
Per i bottoni, un gradiente orizzontale è spesso più leggibile di uno diagonale. Mantiene la label stabile ed evita che il controllo sembri inclinato.
Testo con gradiente e maschera
È il pattern più d'impatto del set, ed è utile se usato con moderazione. Titoli hero, banner di upgrade e headline per gli empty state sono ottimi candidati. Il testo dei paragrafi no.
Ti serviranno @react-native-masked-view/masked-view.
npm install @react-native-masked-view/masked-view
Poi crea la maschera per il testo:
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 conta di più quando vuoi che un colore occupi più spazio visivo di un altro. Se la sfumatura appare spenta, riduci prima il numero di colori. Di solito risolve il design più velocemente che regolare ogni stop.
Animare i gradienti per renderli vivi
I gradienti statici danno rifinitura. I gradienti animati danno feedback.
L'uso più pratico non è uno sfondo appariscente, ma uno shimmer loader. Quell'effetto comunica agli utenti che l'app è attiva, i dati stanno arrivando e il layout è intenzionale e non rotto.

Un componente shimmer completa anche altri pattern di movimento. Se la tua app utilizza già icone animate o loader, questo Guida a Lottie in React Native è utile per decidere quando uno shimmer con gradiente è sufficiente e quando ha più senso usare un asset di animazione più ricco.
Uno shimmer loader dall'effetto nativo
La versione più semplice e affidabile usa react-native-reanimated per far scorrere una banda di gradiente su un placeholder ritagliato.
Installa Reanimated se non è già presente, poi crea un wrapper con overflow: 'hidden'. All'interno, anima un layer di gradiente da sinistra a destra.
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,
},
});
Il segreto è che non stai cercando di animare la definizione del gradiente stessa. Stai animando un layer di gradiente sopra un placeholder statico. È più semplice, facile da gestire e solitamente più stabile su diversi dispositivi.
Ecco un walkthrough visivo dell'effetto in pratica:
Il componente animato
Alcune note sull'implementazione:
- Usa il clipping: Il parent ha bisogno di
overflow: 'hidden', altrimenti lo shimmer uscirà dai bordi arrotondati. - Mantieni la banda stretta: Un layer animato più piccolo è più facile da regolare rispetto all'animazione dell'intera superficie.
- Abbina il colore base allo schermo: Gli skeleton loader dovrebbero integrarsi nel layout circostante, non sembrare un widget separato.
I gradienti animati funzionano meglio quando l'utente quasi non li nota. Se lo shimmer diventa l'elemento più evidente sullo schermo, è eccessivo.
Performance, accessibilità e peculiarità delle piattaforme
Quando i gradienti passano dalle demo alla produzione, le priorità cambiano. Il code sembra ancora semplice, ma il rendering, la leggibilità e la coerenza tra le piattaforme contano più dell'effetto iniziale.
Se stai migliorando la reattività dell'app in modo più ampio, questa guida all'ottimizzazione delle performance mobile condivide la stessa filosofia: ridurre il lavoro superfluo, testare su dispositivi reali e ottimizzare le interfacce più utilizzate dagli utenti.
Checklist delle performance
I gradienti nativi sono generalmente efficienti, ma possono comunque essere usati male.
- Preferisci i gradienti alle grandi immagini decorative: Sono più leggeri da distribuire e più facili da adattare a vari schermi.
- Evita di sovrapporre troppi layer a tutto schermo: Un gradiente di sfondo va bene. Diversi gradienti traslucidi sovrapposti, più blur e animazioni pesanti, possono costare in termini di performance.
- Memoizza i componenti riutilizzabili: Se una card con gradiente è in una lista, mantieni le props stabili ed evita il rerender per stati del parent non correlati.
Una buona regola è usare i gradienti in modo strutturale, non eccessivo. Usali per definire le superfici, non per ogni riga di un feed denso.
Checklist per l'accessibilità
I gradienti possono compromettere la leggibilità perché il contrasto cambia lungo la superficie.
- Testa il testo rispetto all'area più chiara: Se il testo bianco funziona solo sulla parte scura della sfumatura, non va bene.
- Aggiungi uno scrim quando necessario: Un leggero overlay scuro tra sfondo e testo è spesso meglio che cambiare l'intera palette.
- Riserva il testo con gradiente per i titoli grandi: Funziona bene nei titoli. È una scelta pessima per label piccole, testi di supporto o elementi critici per completare un task.
Controlla il punto peggiore del gradiente, non quello più bello.
Checklist delle particolarità delle piattaforme
iOS e Android solitamente renderizzano lo stesso gradiente in modo simile, ma non sempre perfettamente.
| Problema | Cosa aiuta di solito |
|---|---|
| Il gradiente appare diverso tra le piattaforme | Usa meno colori e un contrasto più netto tra gli stop |
| Gli angoli arrotondati non tagliano il gradiente | Inserisci overflow: 'hidden' sul contenitore |
| Il gradiente non appare affatto | Controlla larghezza, altezza o flex: 1 first |
Controlla anche la status bar e la gestione della safe area. Un gradiente bilanciato nel simulatore potrebbe sembrare troppo alto su un dispositivo con notch, se il contenuto e lo sfondo non tengono conto di quello spazio extra.
Troubleshooting e Best Practice finali
Ecco la versione breve che terrei in una nota di progetto.
- Scegli la libreria in base al workflow:
expo-linear-gradientper app gestite con Expo,react-native-linear-gradientper React Native bare. - Usa i gradienti con uno scopo: Sfondi, CTA, overlay e hero text sono ottimi casi d'uso.
- Controlla la direzione con criterio: Orizzontale per i bottoni, diagonale per sfondi decorativi, con maschera solo per testi grandi.
- Progetta per i contenuti, non per gli stati vuoti: Testa con testi reali, icone e il trattamento della status bar.
- Tratta il setup base come un setup nativo: Pods, linking e Jest mock non sono dettagli opzionali.
Tre errori comuni si presentano ripetutamente.
Il gradiente non appare
Causa: il componente non ha dimensioni visibili.
Soluzione: assegna flex: 1un'altezza esplicita o un parent con dimensioni. Un gradiente senza un layout box non verrà renderizzato correttamente.
La build iOS si rompe dopo l'installazione
Causa: i pod non sono stati installati o il grafo delle dipendenze native è fuori sincrono.
Risolto: esegui pod install in ios, pulisci la cartella di build se necessario, poi ricostruisci l'app. Nei progetti bare, la sola installazione dei package di solito non basta.
I test falliscono con errori sui moduli nativi
Causa: Jest sta cercando di caricare il modulo nativo reale.
Soluzione: mocka react-native-linear-gradient con react-native-linear-gradient/jest/linear-gradient-mock nel tuo file di setup di Jest.
Se dovessi ricordare un solo concetto di questa guida, ricorda questo: il gradiente in sé è semplice. La parte difficile è il setup per la produzione. Una volta scelta la libreria giusta per l'architettura della tua app, tutto il resto diventa molto più prevedibile.
Se il tuo team rilascia app mobile ibride e vuole pubblicare aggiornamenti di JavaScript, CSS, copy, config e asset senza attendere la revisione degli store, Capgo merita un'occhiata. Offre ai team di CapacitorJS ed Electron live updates controllati, canali di rollout, protezione dai rollback e visibilità sui rilasci, senza trasformare il processo di deployment in una black box.