# 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