# React Native: 2026'da Eksiksiz Bir Mobil Uygulama Gelistirmek > React Native ile iOS ve Android icin mobil uygulama gelistirmenin kapsamli rehberi. Kurulumdan yayinlamaya kadar tum temel bilgiler. - Published: 2026-01-10 - Updated: 2026-04-06 - Author: SharpSkill - Tags: react native, mobile development, javascript, ios, android - Reading time: 15 min --- React Native, tek bir JavaScript kod tabaniylahem iOS hem de Android icin yerel mobil uygulamalar olusturmayi mumkun kilar. Meta tarafindan gelistirilen ve Instagram, Facebook, Discord gibi uygulamalarda kullanilan bu framework, yerel performanstan odun vermeden hizli bir gelistirme deneyimi sunar. > **Why React Native in 2026?** > > Yeni mimari (Fabric ve TurboModules) artik kararli hale geldi. React Native, web gelistirme verimliligi koruyarak yerele yakin performans sunuyor. En populer 500 uygulamanin yuzde 40'indan fazlasi React Native kullaniyor. ## Development Environment Setup Calismaya baslamadan once gerekli araclarin kurulmasi gerekir. React Native iki yaklasim sunar: Expo (yeni baslayanlara onerilen) ve React Native CLI (daha fazla kontrol saglayan). ```bash # setup.sh # Node.js installation (LTS version recommended) # Check installed version node --version # >= 18.x required npm --version # >= 9.x required # Install Expo CLI tool globally npm install -g expo-cli # Create a new project with Expo npx create-expo-app@latest MyApp --template blank-typescript # Navigate to the project cd MyApp # Start the development server npx expo start ``` Expo, yerel yapilandirmalari otomatik olarak yoneterek gelistirme surecini onemli olcude basitlestirir. Uygulamayi test etmek icin akilli telefona Expo Go yuklenmesi ve ekranda beliren QR kodunun taranmasi yeterlidir. ```bash # structure.sh # Generated project structure MyApp/ ├── App.tsx # Application entry point ├── app.json # Expo configuration ├── package.json # Dependencies ├── tsconfig.json # TypeScript configuration ├── babel.config.js # Babel configuration └── assets/ # Images and resources ├── icon.png └── splash.png ``` ## Core React Native Components React Native, HTML elementlerinin yerini alan yerel bilesenler sunar. Her bilesen dogrudan iOS veya Android yerel bilesenlerine donusturulur. ```tsx // App.tsx import React from 'react'; import { View, Text, StyleSheet, SafeAreaView, StatusBar } from 'react-native'; // Main application component export default function App() { return ( // SafeAreaView prevents overlap with status bar {/* StatusBar configures system bar appearance */} {/* View is the equivalent of div */} {/* Text is required to display text */} Welcome to MyApp A React Native application ); } // StyleSheet.create optimizes styles for native const styles = StyleSheet.create({ container: { flex: 1, // Takes all available space backgroundColor: '#ffffff', }, header: { padding: 20, alignItems: 'center', // Centers horizontally justifyContent: 'center', // Centers vertically }, title: { fontSize: 24, fontWeight: 'bold', color: '#1a1a1a', marginBottom: 8, }, subtitle: { fontSize: 16, color: '#666666', }, }); ``` > **Flexbox by Default** > > React Native varsayilan olarak `flexDirection: 'column'` ile Flexbox kullanir (web'de varsayilan `row`'dur). Bu fark, yerlesim tasarimi acisindan onemlidir. ## Handling User Interactions Dokunma etkilesimleri ozellestirilmis bilesenler araciligiyla yonetilir. Her etkilesim turu, performans optimizasyonu icin kendine ozgu bir bilesene sahiptir. ```tsx // components/InteractiveButton.tsx import React, { useState } from 'react'; import { TouchableOpacity, TouchableHighlight, Pressable, Text, StyleSheet, View, } from 'react-native'; // Button component with different interaction styles export function InteractiveButton() { const [count, setCount] = useState(0); return ( {/* TouchableOpacity reduces opacity on touch */} setCount(c => c + 1)} > Counter: {count} {/* Pressable offers more control over states */} [ styles.button, styles.pressableButton, pressed && styles.buttonPressed, ]} onPress={() => console.log('Pressed!')} onLongPress={() => console.log('Long press!')} > {({ pressed }) => ( {pressed ? 'Pressed!' : 'Press here'} )} ); } const styles = StyleSheet.create({ container: { gap: 16, padding: 20, }, button: { backgroundColor: '#007AFF', paddingVertical: 14, paddingHorizontal: 28, borderRadius: 10, alignItems: 'center', }, pressableButton: { backgroundColor: '#34C759', }, buttonPressed: { backgroundColor: '#2DA44E', transform: [{ scale: 0.98 }], }, buttonText: { color: '#ffffff', fontSize: 16, fontWeight: '600', }, }); ``` ## Screen Navigation with React Navigation Navigasyon, her mobil uygulamanin vazgecilmez bir parcasidir. React Navigation, mobil kaliplara uygun farkli navigasyon turleri sunan standart cozumdur. ```bash # install-navigation.sh # Installing navigation dependencies npx expo install @react-navigation/native npx expo install @react-navigation/native-stack npx expo install react-native-screens react-native-safe-area-context ``` ```tsx // App.tsx import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; // Screen imports import { HomeScreen } from './screens/HomeScreen'; import { DetailScreen } from './screens/DetailScreen'; import { ProfileScreen } from './screens/ProfileScreen'; // Type definition for TypeScript navigation export type RootStackParamList = { Home: undefined; // No parameters Detail: { itemId: number; title: string }; // Required parameters Profile: { userId?: string }; // Optional parameter }; // Creating typed navigator const Stack = createNativeStackNavigator(); export default function App() { return ( // NavigationContainer manages navigation state ({ title: route.params.title })} /> ); } ``` ```tsx // screens/HomeScreen.tsx import React from 'react'; import { View, Text, FlatList, TouchableOpacity, StyleSheet } from 'react-native'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; import { RootStackParamList } from '../App'; // Typing navigation props type Props = NativeStackScreenProps; // Sample data const ITEMS = [ { id: 1, title: 'First item' }, { id: 2, title: 'Second item' }, { id: 3, title: 'Third item' }, ]; export function HomeScreen({ navigation }: Props) { return ( {/* FlatList for performant lists */} item.id.toString()} renderItem={({ item }) => ( { // Navigation with typed parameters navigation.navigate('Detail', { itemId: item.id, title: item.title, }); }} > {item.title} )} ItemSeparatorComponent={() => } /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', }, item: { backgroundColor: '#ffffff', padding: 20, }, itemText: { fontSize: 16, color: '#1a1a1a', }, separator: { height: 1, backgroundColor: '#e0e0e0', }, }); ``` ## State Management with Context and Hooks Basit ve orta duzeydeki durum yonetimi icin React Context ve hook'lar, harici bagimliliklara ihtiyac duymadan etkili bir cozum sunar. ```tsx // context/AuthContext.tsx import React, { createContext, useContext, useState, useCallback } from 'react'; // Types for authentication interface User { id: string; email: string; name: string; } interface AuthContextType { user: User | null; isLoading: boolean; signIn: (email: string, password: string) => Promise; signOut: () => void; } // Creating context with default value const AuthContext = createContext(undefined); // Provider that wraps the application export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(false); // Sign in function const signIn = useCallback(async (email: string, password: string) => { setIsLoading(true); try { // Simulated API call const response = await fetch('https://api.example.com/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }), }); const data = await response.json(); setUser(data.user); } catch (error) { console.error('Login error:', error); throw error; } finally { setIsLoading(false); } }, []); // Sign out function const signOut = useCallback(() => { setUser(null); }, []); return ( {children} ); } // Custom hook to use the context export function useAuth() { const context = useContext(AuthContext); if (context === undefined) { throw new Error('useAuth must be used within an AuthProvider'); } return context; } ``` ```tsx // screens/LoginScreen.tsx import React, { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, ActivityIndicator, Alert, } from 'react-native'; import { useAuth } from '../context/AuthContext'; export function LoginScreen() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const { signIn, isLoading } = useAuth(); // Form submission handler const handleSubmit = async () => { if (!email || !password) { Alert.alert('Error', 'Please fill in all fields'); return; } try { await signIn(email, password); } catch (error) { Alert.alert('Error', 'Invalid credentials'); } }; return ( Login {isLoading ? ( ) : ( Sign In )} ); } const styles = StyleSheet.create({ container: { flex: 1, padding: 20, justifyContent: 'center', backgroundColor: '#ffffff', }, title: { fontSize: 28, fontWeight: 'bold', marginBottom: 32, textAlign: 'center', }, input: { borderWidth: 1, borderColor: '#e0e0e0', borderRadius: 10, padding: 16, marginBottom: 16, fontSize: 16, backgroundColor: '#f9f9f9', }, button: { backgroundColor: '#007AFF', padding: 16, borderRadius: 10, alignItems: 'center', marginTop: 8, }, buttonDisabled: { backgroundColor: '#99c9ff', }, buttonText: { color: '#ffffff', fontSize: 18, fontWeight: '600', }, }); ``` > **Global vs Local State** > > Kapsamli paylasilan duruma sahip daha karmasik uygulamalarda Zustand veya Redux Toolkit gibi cozumler tercih edilebilir. Context, seyrek degisen durumlar (tema, kimlik dogrulama) icin en uygunudur. ## API Calls and Data Management Backend iletisimi her mobil uygulamanin merkezinde yer alir. Asagidaki yaklasim, API cagrilari icin bir soyutlama katmani kullanir. ```tsx // services/api.ts // Base API configuration const API_BASE_URL = 'https://api.example.com'; // Type for API errors interface ApiError { message: string; code: string; status: number; } // Utility function for requests async function request( endpoint: string, options: RequestInit = {} ): Promise { const url = `${API_BASE_URL}${endpoint}`; const config: RequestInit = { ...options, headers: { 'Content-Type': 'application/json', ...options.headers, }, }; try { const response = await fetch(url, config); if (!response.ok) { const error: ApiError = await response.json(); throw new Error(error.message || 'An error occurred'); } return response.json(); } catch (error) { // Network error handling if (error instanceof TypeError) { throw new Error('Network connection issue'); } throw error; } } // Types for entities interface Product { id: string; name: string; price: number; description: string; imageUrl: string; } // Products service export const productApi = { // Get all products getAll: () => request('/products'), // Get product by ID getById: (id: string) => request(`/products/${id}`), // Create a product create: (data: Omit) => request('/products', { method: 'POST', body: JSON.stringify(data), }), // Update a product update: (id: string, data: Partial) => request(`/products/${id}`, { method: 'PATCH', body: JSON.stringify(data), }), }; ``` ```tsx // hooks/useProducts.ts import { useState, useEffect, useCallback } from 'react'; import { productApi } from '../services/api'; interface Product { id: string; name: string; price: number; description: string; imageUrl: string; } // Custom hook for product management export function useProducts() { const [products, setProducts] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // Initial products loading const fetchProducts = useCallback(async () => { setIsLoading(true); setError(null); try { const data = await productApi.getAll(); setProducts(data); } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error'); } finally { setIsLoading(false); } }, []); // Refresh (pull-to-refresh) const refresh = useCallback(async () => { await fetchProducts(); }, [fetchProducts]); // Load on mount useEffect(() => { fetchProducts(); }, [fetchProducts]); return { products, isLoading, error, refresh, }; } ``` ```tsx // screens/ProductListScreen.tsx import React from 'react'; import { View, Text, FlatList, Image, StyleSheet, RefreshControl, ActivityIndicator, } from 'react-native'; import { useProducts } from '../hooks/useProducts'; export function ProductListScreen() { const { products, isLoading, error, refresh } = useProducts(); // Display during initial loading if (isLoading && products.length === 0) { return ( Loading... ); } // Display on error if (error) { return ( {error} ); } return ( item.id} contentContainerStyle={styles.list} // Pull-to-refresh refreshControl={ } renderItem={({ item }) => ( {item.name} ${item.price.toFixed(2)} )} /> ); } const styles = StyleSheet.create({ centered: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, loadingText: { marginTop: 12, fontSize: 16, color: '#666666', }, errorText: { fontSize: 16, color: '#FF3B30', textAlign: 'center', }, list: { padding: 16, }, card: { backgroundColor: '#ffffff', borderRadius: 12, marginBottom: 16, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, image: { width: '100%', height: 200, borderTopLeftRadius: 12, borderTopRightRadius: 12, }, cardContent: { padding: 16, }, productName: { fontSize: 18, fontWeight: '600', color: '#1a1a1a', marginBottom: 4, }, productPrice: { fontSize: 16, color: '#007AFF', fontWeight: '500', }, }); ``` ## Local Data Storage Yerel depolama, oturumlar arasinda verilerin kalici olmasini saglar. AsyncStorage basit veriler icin standart cozumdur; karmasik yapilandirmalar icin ise SQLite tercih edilir. ```tsx // services/storage.ts import AsyncStorage from '@react-native-async-storage/async-storage'; // Required installation: npx expo install @react-native-async-storage/async-storage // Centralized storage keys const STORAGE_KEYS = { USER_TOKEN: '@app/user_token', USER_PREFERENCES: '@app/user_preferences', ONBOARDING_COMPLETE: '@app/onboarding_complete', } as const; // Types for user preferences interface UserPreferences { theme: 'light' | 'dark' | 'system'; notifications: boolean; language: string; } // Typed storage service export const storage = { // Authentication token async getToken(): Promise { return AsyncStorage.getItem(STORAGE_KEYS.USER_TOKEN); }, async setToken(token: string): Promise { await AsyncStorage.setItem(STORAGE_KEYS.USER_TOKEN, token); }, async removeToken(): Promise { await AsyncStorage.removeItem(STORAGE_KEYS.USER_TOKEN); }, // User preferences (JSON object) async getPreferences(): Promise { const data = await AsyncStorage.getItem(STORAGE_KEYS.USER_PREFERENCES); return data ? JSON.parse(data) : null; }, async setPreferences(prefs: UserPreferences): Promise { await AsyncStorage.setItem( STORAGE_KEYS.USER_PREFERENCES, JSON.stringify(prefs) ); }, // Onboarding async isOnboardingComplete(): Promise { const value = await AsyncStorage.getItem(STORAGE_KEYS.ONBOARDING_COMPLETE); return value === 'true'; }, async setOnboardingComplete(): Promise { await AsyncStorage.setItem(STORAGE_KEYS.ONBOARDING_COMPLETE, 'true'); }, // Complete cleanup async clearAll(): Promise { const keys = Object.values(STORAGE_KEYS); await AsyncStorage.multiRemove(keys); }, }; ``` > **Sensitive Data Security** > > Kimlik dogrulama tokenlari gibi hassas veriler icin expo-secure-store kullanilmalidir. Bu kutuphane, iOS Keychain ve Android Keystore araciligiyla verileri sifreler. ## Responsive Styles and Theming Profesyonel bir uygulama farkli ekran boyutlarina uyum saglamali ve karanlik modu desteklemelidir. ```tsx // theme/index.ts import { Dimensions, PixelRatio, Platform } from 'react-native'; const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window'); // Reference dimensions (iPhone 14) const guidelineBaseWidth = 390; const guidelineBaseHeight = 844; // Scaling functions export const scale = (size: number) => (SCREEN_WIDTH / guidelineBaseWidth) * size; export const verticalScale = (size: number) => (SCREEN_HEIGHT / guidelineBaseHeight) * size; export const moderateScale = (size: number, factor = 0.5) => size + (scale(size) - size) * factor; // Light theme export const lightTheme = { colors: { primary: '#007AFF', secondary: '#5856D6', success: '#34C759', warning: '#FF9500', error: '#FF3B30', background: '#FFFFFF', surface: '#F2F2F7', text: '#000000', textSecondary: '#8E8E93', border: '#E5E5EA', }, spacing: { xs: scale(4), sm: scale(8), md: scale(16), lg: scale(24), xl: scale(32), }, typography: { h1: { fontSize: moderateScale(32), fontWeight: 'bold' as const, lineHeight: moderateScale(40), }, h2: { fontSize: moderateScale(24), fontWeight: 'bold' as const, lineHeight: moderateScale(32), }, body: { fontSize: moderateScale(16), lineHeight: moderateScale(24), }, caption: { fontSize: moderateScale(14), lineHeight: moderateScale(20), }, }, borderRadius: { sm: scale(4), md: scale(8), lg: scale(12), full: 9999, }, }; // Dark theme export const darkTheme = { ...lightTheme, colors: { ...lightTheme.colors, background: '#000000', surface: '#1C1C1E', text: '#FFFFFF', textSecondary: '#8E8E93', border: '#38383A', }, }; export type Theme = typeof lightTheme; ``` ```tsx // context/ThemeContext.tsx import React, { createContext, useContext, useState, useEffect } from 'react'; import { useColorScheme } from 'react-native'; import { lightTheme, darkTheme, Theme } from '../theme'; import { storage } from '../services/storage'; interface ThemeContextType { theme: Theme; isDark: boolean; toggleTheme: () => void; setThemeMode: (mode: 'light' | 'dark' | 'system') => void; } const ThemeContext = createContext(undefined); export function ThemeProvider({ children }: { children: React.ReactNode }) { const systemColorScheme = useColorScheme(); const [themeMode, setThemeMode] = useState<'light' | 'dark' | 'system'>('system'); // Determine effective theme const isDark = themeMode === 'system' ? systemColorScheme === 'dark' : themeMode === 'dark'; const theme = isDark ? darkTheme : lightTheme; // Load preferences on startup useEffect(() => { storage.getPreferences().then((prefs) => { if (prefs?.theme) { setThemeMode(prefs.theme); } }); }, []); // Toggle between light and dark const toggleTheme = () => { const newMode = isDark ? 'light' : 'dark'; setThemeMode(newMode); storage.getPreferences().then((prefs) => { storage.setPreferences({ ...prefs, theme: newMode, notifications: prefs?.notifications ?? true, language: prefs?.language ?? 'en', }); }); }; return ( {children} ); } export function useTheme() { const context = useContext(ThemeContext); if (!context) { throw new Error('useTheme must be used within a ThemeProvider'); } return context; } ``` ## Preparing for Publication Bir uygulamayi yayinlamadan once birkac yapilandirma ve optimizasyon adiminin tamamlanmasi gerekir. ```json // app.json { "expo": { "name": "MyApp", "slug": "my-app", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", "userInterfaceStyle": "automatic", "splash": { "image": "./assets/splash.png", "resizeMode": "contain", "backgroundColor": "#007AFF" }, "ios": { "supportsTablet": true, "bundleIdentifier": "com.example.myapp", "buildNumber": "1" }, "android": { "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#007AFF" }, "package": "com.example.myapp", "versionCode": 1 }, "plugins": [ "expo-router" ] } } ``` ```bash # build.sh # EAS Build configuration (Expo Application Services) npm install -g eas-cli # Log in to Expo account eas login # Configure the project eas build:configure # Build for iOS (simulator) eas build --platform ios --profile development # Build for Android (test APK) eas build --platform android --profile preview # Production build eas build --platform all --profile production # Store submission eas submit --platform ios eas submit --platform android ``` > **Certificates and Keys** > > iOS'ta yayinlama icin Apple Developer hesabi (yillik 99 USD), Android'de ise Google Play Console hesabi (tek seferlik 25 USD) gereklidir. EAS, imza sertifikalarini otomatik olarak yonetir. ## Conclusion React Native, platformlar arasi mobil uygulama gelistirme icin verimli bir yaklasim sunar. Bu rehberde ele alinan temel konular, eksiksiz ve profesyonel uygulamalar olusturmak icin yeterli altyapiyi saglar. ### Checklist for a Successful React Native App - Hizli baslangicc icin Expo ile ortam kurulumu - Temel bilesenlere hakimiyet: View, Text, TouchableOpacity, FlatList - React Navigation ve TypeScript tip tanimlariyla navigasyon uygulamasi - Context API ve ozel hook'larla durum yonetimi - Ozel servis katmaniyla API cagrilarinin yapilandirilmasi - AsyncStorage ile yerel veri kaliciligi - Karanlik mod destekli duyarli tema sistemi olusturulmasi Resmi React Native ve Expo dokumantasyonu, her konuyu derinlestirmek icin temel basvuru kaynagi olmaya devam etmektedir. Ekosistem hizla gelisiyor ve React Query veya Zustand gibi kutuphaneler, daha karmasik uygulamalarda veri yonetimini daha da kolaylastirabilir. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/tr/blog/react-native/react-native-building-complete-mobile-app