React Native App-ontwikkeling 2026: Complete Gids en Sollicitatievragen
De complete gids voor React Native app-ontwikkeling in 2026. JSI, Fabric, New Architecture, performance-optimalisatie en veelgestelde sollicitatievragen voor ontwikkelaars.

React Native app-ontwikkeling heeft in 2026 een fundamentele transformatie ondergaan. Met versie 0.87 is de New Architecture nu de enige ondersteunde optie. De oude bridge die elke JavaScript-naar-native aanroep als JSON serialiseerde, bestaat niet meer. In plaats daarvan komt JSI (JavaScript Interface) voor directe synchrone communicatie.
React Native 0.87 maakt de New Architecture verplicht. De oude bridge is volledig verwijderd. Complexe lijst-rendering draait 43% sneller, scroll frame drops zijn met 95% afgenomen en het geheugengebruik is met 33% gedaald in benchmark-tests.
JSI en de New Architecture begrijpen
JSI (JavaScript Interface) vervangt de asynchrone bridge door directe C++-bindingen tussen JavaScript en native code. In plaats van data naar JSON te serialiseren, het door een message queue te sturen en aan de andere kant te deserialiseren, maakt JSI het mogelijk dat JavaScript referenties naar native objecten behoudt en hun methodes direct aanroept.
Deze architectonische verschuiving maakt drie kernmogelijkheden mogelijk: synchrone native aanroepen, gedeeld ownership van objecten tussen JavaScript- en native-lagen, en lazy loading van native modules.
import { TurboModuleRegistry, TurboModule } from 'react-native';
export interface Spec extends TurboModule {
getUserProfile(userId: string): Promise<{
id: string;
name: string;
email: string;
}>;
// Synchrone aanroep - alleen mogelijk met JSI
getDeviceLocale(): string;
}
export default TurboModuleRegistry.getEnforcing<Spec>('UserModule');De getDeviceLocale()-methode retourneert direct zonder op een Promise te wachten. Dit was onmogelijk met de oude bridge, waar elke native aanroep asynchrone serialisatie vereiste.
Productie-klare Componenten bouwen met Fabric
Fabric is het nieuwe renderingsysteem dat samenwerkt met JSI. Het beheert de UI-boom in C++ en synchroniseert direct met de JavaScript-thread, waardoor het "UI jank" wordt geëlimineerd dat optrad wanneer de oude bridge niet kon bijhouden tijdens snelle updates.
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}>Niet beschikbaar</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,
},
});De combinatie van memo, useCallback en useSharedValue zorgt ervoor dat animaties op de UI-thread draaien zonder de JavaScript-thread te blokkeren. react-native-reanimated integreert direct met Fabric en kan animaties uitvoeren op 60+ FPS.
State Management met Zustand
Zustand heeft zich gevestigd als de voorkeursoplossing voor state management in React Native. De minimale boilerplate en compatibiliteit met Concurrent React maken het ideaal voor mobiele applicaties.
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),
}
)
);De store persisteert de winkelwagen in AsyncStorage en herstelt automatisch de state wanneer de app opnieuw wordt gestart. De middleware-compositie maakt dit mogelijk met minimale setup.
Navigatie met Expo Router
Expo Router brengt op bestanden gebaseerde routing naar React Native. De mappenstructuur definieert de app-navigatie, vergelijkbaar met Next.js in het web-ecosysteem.
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: 'Zoeken',
tabBarIcon: ({ color, size }) => (
<Search size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="cart"
options={{
title: 'Winkelwagen',
tabBarIcon: ({ color, size }) => (
<ShoppingCart size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Profiel',
tabBarIcon: ({ color, size }) => (
<User size={size} color={color} />
),
}}
/>
</Tabs>
);
}Data Fetching met TanStack Query
TanStack Query (voorheen React Query) beheert de server state. De bibliotheek zorgt voor caching, revalidatie en achtergrond-updates, zodat ontwikkelaars zich kunnen concentreren op de 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'] });
},
});
}Performance-optimalisatie voor Lijsten
FlashList van Shopify vervangt FlatList voor high-performance lijstweergaven. De bibliotheek recycleert componenten agressief en maakt gebruik van de Fabric-architectuur voor soepel scrollen.
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,
},
});De estimatedItemSize-eigenschap is cruciaal voor de performance. FlashList gebruikt deze waarde voor de initiële layout en past zich vervolgens aan op basis van werkelijke metingen.
Veelgestelde Sollicitatievragen voor React Native Ontwikkelaars
Tijdens sollicitatiegesprekken voor React Native-posities komen bepaalde onderwerpen regelmatig aan bod. De volgende vragen en antwoorden dekken de belangrijkste gebieden.
Wat is het verschil tussen de oude bridge en JSI?
De oude bridge gebruikte asynchrone JSON-serialisatie voor communicatie tussen JavaScript en Native. JSI maakt directe C++-bindingen, synchrone aanroepen en gedeeld object-ownership mogelijk. Dit elimineert de serialisatie-overhead en maakt echte native modules mogelijk.
Hoe werkt Fabric in vergelijking met de oude renderer?
Fabric rendert UI-bomen in C++ in plaats van Java/Objective-C. Dit maakt synchrone metingen, geprioriteerde updates en directe integratie met JSI mogelijk. De Shadow Tree leeft nu op de C++-laag, wat de communicatie tussen threads drastisch vermindert.
Wanneer moeten useCallback en useMemo worden gebruikt?
useCallback moet worden gebruikt voor event handlers die aan child-componenten worden doorgegeven. useMemo is nuttig voor dure berekeningen die afhankelijk zijn van props of state. Beide moeten spaarzaam worden gebruikt omdat ze eigen overhead hebben.
Hoe optimaliseer je de performance van een FlatList?
Gebruik FlashList als alternatief voor FlatList, verstrek getItemLayout of estimatedItemSize, activeer removeClippedSubviews, wrap lijst-items met memo en definieer keyExtractor buiten de render-functie.
Klaar om je React Native gesprekken te halen?
Oefen met onze interactieve simulatoren, flashcards en technische tests.
Conclusie
React Native app-ontwikkeling in 2026 vereist een begrip van de New Architecture met JSI en Fabric. De combinatie van Expo Router voor navigatie, TanStack Query voor server state en Zustand voor client state vormt een solide basis voor productie-klare mobiele applicaties. FlashList en react-native-reanimated zorgen voor de performance die gebruikers verwachten van native apps. Ontwikkelaars die deze technologieën beheersen, zijn uitstekend voorbereid op actuele React Native-projecten en sollicitatiegesprekken.
Zie jij de bug in React Native?
Een echt codefragment, een verborgen bug, één poging per dag. Zonder account uit te proberen.

Geschreven door
Anthony Fillion-MailletOprichter van SharpSkill
Al meer dan 10 jaar fullstack-ontwikkelaar. Hij leidt SharpSkill en staat in voor alles wat hier verschijnt.
Bijgewerkt op 6 september 2026
Tags
Delen
Gerelateerde artikelen

React Native 0.87 en SwiftPM in 2026: Modern iOS Build Systeem en Sollicitatievragen
React Native 0.87 introduceert experimentele Swift Package Manager ondersteuning voor iOS builds. Deze gids behandelt SwiftPM configuratie, de Strict TypeScript API, Metro 0.87 optimalisaties en sollicitatievragen voor senior mobile developers.

React Native en TypeScript in 2026: type-veilige architectuur en sollicitatievragen
Bouw type-veilige React Native-apps met TypeScript, Codegen, TurboModules en de Strict TypeScript API. Architectuurpatronen, getypeerde navigatie, toolchain-vereisten voor 0.87 en sollicitatievragen.

React Native New Architecture in 2026: Hermes V1, Bridgeless Mode en Interviewvragen
Diepgaande analyse van de React Native New Architecture met Hermes V1 engine, Bridgeless Mode, TurboModules en Fabric Renderer. Performance-benchmarks, migratiehandleiding en veelgestelde interviewvragen.