Sviluppo App React Native 2026: Guida Completa e Domande di Colloquio
La guida completa allo sviluppo di app React Native nel 2026. JSI, Fabric, New Architecture, ottimizzazione delle performance e domande frequenti nei colloqui tecnici.

Lo sviluppo di app React Native nel 2026 ha subito una trasformazione radicale. Con la versione 0.87, la New Architecture è diventata l'unica opzione supportata. Il vecchio bridge che serializzava ogni chiamata JavaScript-to-native in JSON non esiste più, sostituito da JSI (JavaScript Interface) per la comunicazione sincrona diretta.
React Native 0.87 rende obbligatoria la New Architecture. Il vecchio bridge è stato completamente rimosso. Il rendering di liste complesse è più veloce del 43%, i frame drop durante lo scroll sono diminuiti del 95% e l'utilizzo della memoria si è ridotto del 33% nei test di benchmark.
Comprendere JSI e la New Architecture
JSI (JavaScript Interface) sostituisce il bridge asincrono con binding C++ diretti tra JavaScript e codice nativo. Invece di serializzare i dati in JSON, passarli attraverso una coda di messaggi e deserializzarli dall'altra parte, JSI permette a JavaScript di mantenere riferimenti agli oggetti nativi e chiamare i loro metodi direttamente.
Questo cambiamento architetturale abilita tre capacità fondamentali: chiamate native sincrone, ownership condiviso degli oggetti tra i layer JavaScript e nativo, e lazy loading dei moduli nativi.
import { TurboModuleRegistry, TurboModule } from 'react-native';
export interface Spec extends TurboModule {
getUserProfile(userId: string): Promise<{
id: string;
name: string;
email: string;
}>;
// Chiamata sincrona - possibile solo con JSI
getDeviceLocale(): string;
}
export default TurboModuleRegistry.getEnforcing<Spec>('UserModule');Il metodo getDeviceLocale() restituisce immediatamente senza attendere una Promise. Questo era impossibile con il vecchio bridge, dove ogni chiamata nativa richiedeva serializzazione asincrona.
Costruire Componenti Production-Ready con Fabric
Fabric è il nuovo sistema di rendering che lavora insieme a JSI. Gestisce l'albero UI in C++ e si sincronizza direttamente con il thread JavaScript, eliminando il "UI jank" che si verificava quando il vecchio bridge non riusciva a tenere il passo durante aggiornamenti rapidi.
import React, { memo, useCallback } from 'react';
import {
View,
Text,
Image,
Pressable,
StyleSheet,
} from 'react-native';
import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
} from 'react-native-reanimated';
interface Product {
id: string;
name: string;
price: number;
imageUrl: string;
inStock: boolean;
}
interface ProductCardProps {
product: Product;
onPress: (id: string) => void;
}
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
export const ProductCard = memo(function ProductCard({
product,
onPress,
}: ProductCardProps) {
const scale = useSharedValue(1);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
}));
const handlePressIn = useCallback(() => {
scale.value = withSpring(0.95);
}, [scale]);
const handlePressOut = useCallback(() => {
scale.value = withSpring(1);
}, [scale]);
const handlePress = useCallback(() => {
onPress(product.id);
}, [onPress, product.id]);
return (
<AnimatedPressable
style={[styles.card, animatedStyle]}
onPressIn={handlePressIn}
onPressOut={handlePressOut}
onPress={handlePress}
>
<Image
source={{ uri: product.imageUrl }}
style={styles.image}
resizeMode="cover"
/>
<View style={styles.content}>
<Text style={styles.name} numberOfLines={2}>
{product.name}
</Text>
<Text style={styles.price}>
€{product.price.toFixed(2)}
</Text>
{!product.inStock && (
<Text style={styles.outOfStock}>Non disponibile</Text>
)}
</View>
</AnimatedPressable>
);
});
const styles = StyleSheet.create({
card: {
backgroundColor: '#ffffff',
borderRadius: 12,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 8,
elevation: 3,
overflow: 'hidden',
},
image: {
width: '100%',
height: 200,
},
content: {
padding: 16,
},
name: {
fontSize: 16,
fontWeight: '600',
color: '#1a1a1a',
marginBottom: 8,
},
price: {
fontSize: 18,
fontWeight: '700',
color: '#2563eb',
},
outOfStock: {
fontSize: 14,
color: '#dc2626',
marginTop: 4,
},
});La combinazione di memo, useCallback e useSharedValue assicura che le animazioni vengano eseguite sul thread UI senza bloccare il thread JavaScript. react-native-reanimated si integra direttamente con Fabric e può eseguire animazioni a 60+ FPS.
Gestione dello State con Zustand
Zustand si è affermato come la soluzione preferita per la gestione dello state in React Native. Il boilerplate minimo e la compatibilità con Concurrent React lo rendono ideale per le applicazioni mobile.
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
interface CartItem {
productId: string;
quantity: number;
price: number;
}
interface CartStore {
items: CartItem[];
addItem: (productId: string, price: number) => void;
removeItem: (productId: string) => void;
updateQuantity: (productId: string, quantity: number) => void;
clearCart: () => void;
total: () => number;
}
export const useCartStore = create<CartStore>()(
persist(
(set, get) => ({
items: [],
addItem: (productId, price) => set((state) => {
const existing = state.items.find(i => i.productId === productId);
if (existing) {
return {
items: state.items.map(i =>
i.productId === productId
? { ...i, quantity: i.quantity + 1 }
: i
),
};
}
return {
items: [...state.items, { productId, quantity: 1, price }],
};
}),
removeItem: (productId) => set((state) => ({
items: state.items.filter(i => i.productId !== productId),
})),
updateQuantity: (productId, quantity) => set((state) => ({
items: quantity > 0
? state.items.map(i =>
i.productId === productId ? { ...i, quantity } : i
)
: state.items.filter(i => i.productId !== productId),
})),
clearCart: () => set({ items: [] }),
total: () => {
return get().items.reduce(
(sum, item) => sum + item.price * item.quantity,
0
);
},
}),
{
name: 'cart-storage',
storage: createJSONStorage(() => AsyncStorage),
}
)
);Lo store persiste il carrello in AsyncStorage e ripristina automaticamente lo stato al riavvio dell'app. La composizione dei middleware rende tutto questo possibile con una configurazione minima.
Navigazione con Expo Router
Expo Router porta il routing basato su file in React Native. La struttura delle cartelle definisce la navigazione dell'app, in modo simile a Next.js nell'ecosistema web.
import { Stack } from 'expo-router';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5,
retry: 2,
},
},
});
export default function RootLayout() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<QueryClientProvider client={queryClient}>
<Stack
screenOptions={{
headerShown: false,
animation: 'slide_from_right',
}}
/>
</QueryClientProvider>
</GestureHandlerRootView>
);
}import { Tabs } from 'expo-router';
import { Home, Search, ShoppingCart, User } from 'lucide-react-native';
export default function TabLayout() {
return (
<Tabs
screenOptions={{
tabBarActiveTintColor: '#2563eb',
tabBarInactiveTintColor: '#6b7280',
headerShown: false,
}}
>
<Tabs.Screen
name="index"
options={{
title: 'Home',
tabBarIcon: ({ color, size }) => (
<Home size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="search"
options={{
title: 'Cerca',
tabBarIcon: ({ color, size }) => (
<Search size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="cart"
options={{
title: 'Carrello',
tabBarIcon: ({ color, size }) => (
<ShoppingCart size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Profilo',
tabBarIcon: ({ color, size }) => (
<User size={size} color={color} />
),
}}
/>
</Tabs>
);
}Data Fetching con TanStack Query
TanStack Query (precedentemente React Query) gestisce lo state del server. La libreria si occupa di caching, revalidazione e aggiornamenti in background, permettendo agli sviluppatori di concentrarsi sulla UI.
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '../lib/api';
interface Product {
id: string;
name: string;
price: number;
imageUrl: string;
inStock: boolean;
category: string;
}
export function useProducts(category?: string) {
return useQuery({
queryKey: ['products', category],
queryFn: () => api.get<Product[]>(`/products`, {
params: category ? { category } : undefined,
}),
staleTime: 1000 * 60 * 5,
});
}
export function useProduct(id: string) {
return useQuery({
queryKey: ['product', id],
queryFn: () => api.get<Product>(`/products/${id}`),
enabled: !!id,
});
}
export function useUpdateProduct() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: Partial<Product> & { id: string }) =>
api.patch<Product>(`/products/${data.id}`, data),
onSuccess: (updatedProduct) => {
queryClient.setQueryData(
['product', updatedProduct.id],
updatedProduct
);
queryClient.invalidateQueries({ queryKey: ['products'] });
},
});
}Ottimizzazione delle Performance per le Liste
FlashList di Shopify sostituisce FlatList per visualizzazioni di liste ad alte prestazioni. La libreria ricicla i componenti in modo aggressivo e sfrutta l'architettura Fabric per uno scrolling fluido.
import React, { useCallback } from 'react';
import { View, StyleSheet, RefreshControl } from 'react-native';
import { FlashList } from '@shopify/flash-list';
import { useProducts } from '../hooks/useProducts';
import { ProductCard } from './ProductCard';
import { ProductSkeleton } from './ProductSkeleton';
interface ProductListProps {
category?: string;
onProductPress: (id: string) => void;
}
export function ProductList({ category, onProductPress }: ProductListProps) {
const {
data: products,
isLoading,
isRefetching,
refetch,
} = useProducts(category);
const renderItem = useCallback(
({ item }: { item: Product }) => (
<ProductCard product={item} onPress={onProductPress} />
),
[onProductPress]
);
const keyExtractor = useCallback(
(item: Product) => item.id,
[]
);
if (isLoading) {
return (
<View style={styles.skeletonContainer}>
{Array.from({ length: 6 }).map((_, i) => (
<ProductSkeleton key={i} />
))}
</View>
);
}
return (
<FlashList
data={products}
renderItem={renderItem}
keyExtractor={keyExtractor}
estimatedItemSize={280}
numColumns={2}
contentContainerStyle={styles.listContent}
refreshControl={
<RefreshControl
refreshing={isRefetching}
onRefresh={refetch}
tintColor="#2563eb"
/>
}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
);
}
const styles = StyleSheet.create({
listContent: {
padding: 16,
},
separator: {
height: 16,
},
skeletonContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
padding: 16,
gap: 16,
},
});La proprietà estimatedItemSize è cruciale per le performance. FlashList utilizza questo valore per il layout iniziale e poi si adatta in base alle misurazioni effettive.
Domande Frequenti nei Colloqui per Sviluppatori React Native
Durante i colloqui per posizioni React Native, alcuni argomenti vengono regolarmente affrontati. Le seguenti domande e risposte coprono le aree più importanti.
Qual è la differenza tra il vecchio bridge e JSI?
Il vecchio bridge utilizzava la serializzazione JSON asincrona per la comunicazione tra JavaScript e Native. JSI abilita binding C++ diretti, chiamate sincrone e ownership condiviso degli oggetti. Questo elimina l'overhead della serializzazione e permette veri moduli nativi.
Come funziona Fabric rispetto al vecchio renderer?
Fabric renderizza gli alberi UI in C++ invece che in Java/Objective-C. Questo permette misurazioni sincrone, aggiornamenti prioritizzati e integrazione diretta con JSI. Lo Shadow Tree ora vive nel layer C++, riducendo drasticamente la comunicazione tra thread.
Quando si dovrebbero usare useCallback e useMemo?
useCallback dovrebbe essere usato per gli event handler passati ai componenti figli. useMemo è utile per calcoli costosi che dipendono da props o state. Entrambi dovrebbero essere usati con parsimonia poiché hanno un proprio overhead.
Come si ottimizzano le performance di una FlatList?
Usare FlashList come alternativa a FlatList, fornire getItemLayout o estimatedItemSize, abilitare removeClippedSubviews, wrappare gli item della lista con memo e definire keyExtractor al di fuori della funzione di render.
Pronto a superare i tuoi colloqui su React Native?
Pratica con i nostri simulatori interattivi, flashcards e test tecnici.
Conclusione
Lo sviluppo di app React Native nel 2026 richiede una comprensione della New Architecture con JSI e Fabric. La combinazione di Expo Router per la navigazione, TanStack Query per lo state del server e Zustand per lo state client forma una solida base per applicazioni mobile pronte per la produzione. FlashList e react-native-reanimated garantiscono le performance che gli utenti si aspettano dalle app native. Gli sviluppatori che padroneggiano queste tecnologie sono perfettamente preparati per i progetti React Native attuali e per i colloqui tecnici.
Sapresti trovare il bug in React Native?
Uno snippet reale, un bug nascosto, un tentativo al giorno. Senza account per provare.

Scritto da
Anthony Fillion-MailletFondatore di SharpSkill
Sviluppatore fullstack da oltre 10 anni. Guida SharpSkill e risponde di tutto ciò che vi viene pubblicato.
Aggiornato il 6 settembre 2026
Tag
Condividi
Articoli correlati

React Native 0.87 e SwiftPM nel 2026: Build iOS Moderno e Domande per Colloqui
React Native 0.87 introduce il supporto sperimentale per Swift Package Manager, eliminando CocoaPods dalle build iOS. Questa guida copre la configurazione di SwiftPM, la Strict TypeScript API, le ottimizzazioni di Metro 0.87 e domande per colloqui di sviluppatori mobile senior.

React Native e TypeScript nel 2026: architettura type-safe e domande da colloquio
Crea app React Native type-safe con TypeScript, Codegen, TurboModule e la Strict TypeScript API. Pattern architetturali, navigazione tipizzata, requisiti toolchain per la 0.87 e domande da colloquio.

React Native New Architecture nel 2026: Hermes V1, Bridgeless Mode e Domande per Colloqui
Analisi approfondita della React Native New Architecture con Hermes V1, Bridgeless Mode, TurboModules e Fabric Renderer. Benchmark di performance, guida alla migrazione e domande frequenti nei colloqui tecnici.