🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
React Native Samples
React Native cross-platform mobile development examples including components, navigation, state management, and native integration
💻 React Native Hello World typescript
🟢 simple
Basic React Native app examples with components, styling, and navigation setup
// React Native Hello World Examples
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
Button,
TextInput,
TouchableOpacity,
Image,
ScrollView,
Alert,
SafeAreaView,
StatusBar,
Platform
} from 'react-native';
// 1. Basic Hello World Component
const HelloWorld = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello, World!</Text>
<Text style={styles.subtitle}>Welcome to React Native</Text>
</View>
);
};
// 2. Component with Props
interface GreetingProps {
name: string;
greeting?: string;
}
const Greeting: React.FC<GreetingProps> = ({ name, greeting = 'Hello' }) => {
return (
<View style={styles.card}>
<Text style={styles.greeting}>{greeting}, {name}!</Text>
<Text style={styles.message}>This component accepts props</Text>
</View>
);
};
// 3. Interactive Counter Component
const Counter: React.FC = () => {
const [count, setCount] = useState(0);
return (
<View style={styles.card}>
<Text style={styles.counterText}>Count: {count}</Text>
<View style={styles.buttonRow}>
<TouchableOpacity
style={styles.button}
onPress={() => setCount(count - 1)}
>
<Text style={styles.buttonText}>-</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={() => setCount(0)}
>
<Text style={styles.buttonText}>Reset</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => setCount(count + 1)}
>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
</View>
</View>
);
};
// 4. User Profile Component
interface UserProfileProps {
initialName?: string;
initialAge?: number;
}
const UserProfile: React.FC<UserProfileProps> = ({
initialName = '',
initialAge = 0
}) => {
const [name, setName] = useState(initialName);
const [age, setAge] = useState(initialAge.toString());
const [isEditing, setIsEditing] = useState(false);
const handleSave = () => {
setIsEditing(false);
Alert.alert('Profile Saved', `Name: ${name}, Age: ${age}`);
};
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>User Profile</Text>
{isEditing ? (
<View>
<TextInput
style={styles.input}
value={name}
onChangeText={setName}
placeholder="Enter your name"
/>
<TextInput
style={styles.input}
value={age}
onChangeText={setAge}
placeholder="Enter your age"
keyboardType="numeric"
/>
<View style={styles.buttonRow}>
<TouchableOpacity
style={[styles.button, styles.saveButton]}
onPress={handleSave}
>
<Text style={styles.buttonText}>Save</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.cancelButton]}
onPress={() => setIsEditing(false)}
>
<Text style={styles.buttonText}>Cancel</Text>
</TouchableOpacity>
</View>
</View>
) : (
<View>
<Text style={styles.profileText}>Name: {name || 'Not set'}</Text>
<Text style={styles.profileText}>Age: {age || 'Not set'}</Text>
<TouchableOpacity
style={[styles.button, styles.editButton]}
onPress={() => setIsEditing(true)}
>
<Text style={styles.buttonText}>Edit Profile</Text>
</TouchableOpacity>
</View>
)}
</View>
);
};
// 5. Todo List Component
interface Todo {
id: number;
text: string;
completed: boolean;
createdAt: Date;
}
const TodoApp: React.FC = () => {
const [todos, setTodos] = useState<Todo[]>([
{ id: 1, text: 'Learn React Native', completed: false, createdAt: new Date() },
{ id: 2, text: 'Build a mobile app', completed: false, createdAt: new Date() }
]);
const [newTodoText, setNewTodoText] = useState('');
const addTodo = () => {
if (newTodoText.trim()) {
const newTodo: Todo = {
id: Date.now(),
text: newTodoText.trim(),
completed: false,
createdAt: new Date()
};
setTodos([newTodo, ...todos]);
setNewTodoText('');
}
};
const toggleTodo = (id: number) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};
const deleteTodo = (id: number) => {
Alert.alert(
'Delete Todo',
'Are you sure you want to delete this todo?',
[
{ text: 'Cancel', style: 'cancel' },
{
text: 'Delete',
style: 'destructive',
onPress: () => setTodos(todos.filter(todo => todo.id !== id))
}
]
);
};
const completedCount = todos.filter(todo => todo.completed).length;
const activeCount = todos.filter(todo => !todo.completed).length;
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Todo List</Text>
<View style={styles.inputContainer}>
<TextInput
style={styles.todoInput}
value={newTodoText}
onChangeText={setNewTodoText}
placeholder="What needs to be done?"
onSubmitEditing={addTodo}
/>
<TouchableOpacity style={styles.addButton} onPress={addTodo}>
<Text style={styles.addButtonText}>+</Text>
</TouchableOpacity>
</View>
<View style={styles.statsContainer}>
<Text style={styles.statText}>
{activeCount} active, {completedCount} completed
</Text>
</View>
<ScrollView style={styles.todoList}>
{todos.map((todo) => (
<View key={todo.id} style={styles.todoItem}>
<TouchableOpacity
style={styles.todoCheckbox}
onPress={() => toggleTodo(todo.id)}
>
<View style={[
styles.checkbox,
todo.completed && styles.checkboxChecked
]}>
{todo.completed && <Text style={styles.checkmark}>✓</Text>}
</View>
</TouchableOpacity>
<View style={styles.todoContent}>
<Text style={[
styles.todoText,
todo.completed && styles.todoTextCompleted
]}>
{todo.text}
</Text>
<Text style={styles.todoDate}>
{todo.createdAt.toLocaleDateString()}
</Text>
</View>
<TouchableOpacity
style={styles.deleteButton}
onPress={() => deleteTodo(todo.id)}
>
<Text style={styles.deleteButtonText}>×</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
);
};
// 6. Main App Component
const App: React.FC = () => {
const [activeComponent, setActiveComponent] = useState<string>('all');
const renderComponent = () => {
switch (activeComponent) {
case 'greeting':
return <Greeting name="React Native Developer" />;
case 'counter':
return <Counter />;
case 'profile':
return <UserProfile initialName="John Doe" initialAge={25} />;
case 'todo':
return <TodoApp />;
default:
return (
<>
<HelloWorld />
<Greeting name="Mobile Developer" />
<Counter />
<UserProfile />
<TodoApp />
</>
);
}
};
return (
<SafeAreaView style={styles.safeArea}>
<StatusBar
barStyle="light-content"
backgroundColor="#2c3e50"
/>
<View style={styles.header}>
<Text style={styles.headerTitle}>React Native Demo</Text>
<Text style={styles.headerSubtitle}>
Platform: {Platform.OS === 'ios' ? 'iOS' : 'Android'}
</Text>
</View>
<View style={styles.navigation}>
{['all', 'greeting', 'counter', 'profile', 'todo'].map((component) => (
<TouchableOpacity
key={component}
style={[
styles.navButton,
activeComponent === component && styles.activeNavButton
]}
onPress={() => setActiveComponent(component)}
>
<Text style={[
styles.navButtonText,
activeComponent === component && styles.activeNavButtonText
]}>
{component.charAt(0).toUpperCase() + component.slice(1)}
</Text>
</TouchableOpacity>
))}
</View>
<ScrollView style={styles.content}>
{renderComponent()}
</ScrollView>
</SafeAreaView>
);
};
// Styles
const styles = StyleSheet.create({
safeArea: {
flex: 1,
backgroundColor: '#f8f9fa',
},
container: {
padding: 20,
alignItems: 'center',
backgroundColor: '#fff',
margin: 16,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#2c3e50',
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: '#7f8c8d',
textAlign: 'center',
},
card: {
backgroundColor: '#fff',
margin: 16,
padding: 20,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
cardTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#2c3e50',
marginBottom: 16,
textAlign: 'center',
},
greeting: {
fontSize: 20,
fontWeight: '600',
color: '#3498db',
textAlign: 'center',
marginBottom: 8,
},
message: {
fontSize: 14,
color: '#7f8c8d',
textAlign: 'center',
},
counterText: {
fontSize: 24,
fontWeight: 'bold',
color: '#2c3e50',
textAlign: 'center',
marginBottom: 16,
},
buttonRow: {
flexDirection: 'row',
justifyContent: 'center',
gap: 12,
},
button: {
backgroundColor: '#ecf0f1',
paddingHorizontal: 20,
paddingVertical: 12,
borderRadius: 6,
minWidth: 60,
alignItems: 'center',
},
primaryButton: {
backgroundColor: '#3498db',
},
saveButton: {
backgroundColor: '#27ae60',
},
cancelButton: {
backgroundColor: '#e74c3c',
},
editButton: {
backgroundColor: '#f39c12',
},
buttonText: {
color: '#2c3e50',
fontSize: 16,
fontWeight: '600',
},
input: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 6,
padding: 12,
fontSize: 16,
marginBottom: 12,
backgroundColor: '#fff',
},
profileText: {
fontSize: 16,
color: '#2c3e50',
marginBottom: 8,
},
inputContainer: {
flexDirection: 'row',
marginBottom: 16,
},
todoInput: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 6,
padding: 12,
fontSize: 16,
marginRight: 8,
},
addButton: {
backgroundColor: '#27ae60',
width: 48,
height: 48,
borderRadius: 6,
justifyContent: 'center',
alignItems: 'center',
},
addButtonText: {
color: '#fff',
fontSize: 24,
fontWeight: 'bold',
},
statsContainer: {
marginBottom: 16,
padding: 12,
backgroundColor: '#ecf0f1',
borderRadius: 6,
},
statText: {
textAlign: 'center',
color: '#7f8c8d',
fontSize: 14,
},
todoList: {
maxHeight: 300,
},
todoItem: {
flexDirection: 'row',
alignItems: 'center',
padding: 12,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#ecf0f1',
},
todoCheckbox: {
marginRight: 12,
},
checkbox: {
width: 24,
height: 24,
borderWidth: 2,
borderColor: '#ddd',
borderRadius: 4,
justifyContent: 'center',
alignItems: 'center',
},
checkboxChecked: {
backgroundColor: '#27ae60',
borderColor: '#27ae60',
},
checkmark: {
color: '#fff',
fontSize: 16,
fontWeight: 'bold',
},
todoContent: {
flex: 1,
},
todoText: {
fontSize: 16,
color: '#2c3e50',
},
todoTextCompleted: {
textDecorationLine: 'line-through',
color: '#7f8c8d',
},
todoDate: {
fontSize: 12,
color: '#95a5a6',
marginTop: 4,
},
deleteButton: {
padding: 8,
backgroundColor: '#e74c3c',
borderRadius: 4,
},
deleteButtonText: {
color: '#fff',
fontSize: 18,
fontWeight: 'bold',
},
header: {
backgroundColor: '#2c3e50',
padding: 20,
paddingTop: Platform.OS === 'ios' ? 40 : 20,
},
headerTitle: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
textAlign: 'center',
},
headerSubtitle: {
fontSize: 14,
color: '#ecf0f1',
textAlign: 'center',
marginTop: 4,
},
navigation: {
flexDirection: 'row',
backgroundColor: '#34495e',
paddingVertical: 8,
},
navButton: {
flex: 1,
paddingVertical: 12,
alignItems: 'center',
},
activeNavButton: {
backgroundColor: '#2c3e50',
},
navButtonText: {
color: '#ecf0f1',
fontSize: 14,
fontWeight: '500',
},
activeNavButtonText: {
color: '#3498db',
fontWeight: 'bold',
},
content: {
flex: 1,
},
});
export default App;
💻 React Native Navigation typescript
🟡 intermediate
Navigation patterns and routing in React Native using React Navigation
// React Native Navigation Examples
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
Button,
TouchableOpacity,
Image,
ScrollView,
TextInput,
Alert
} from 'react-native';
import {
NavigationContainer,
createNativeStackNavigator,
NativeStackNavigationProp,
NativeStackScreenProps,
} from '@react-navigation/native-stack';
import {
createBottomTabNavigator,
BottomTabNavigationProp,
} from '@react-navigation/bottom-tabs';
import {
createDrawerNavigator,
DrawerNavigationProp,
} from '@react-navigation/drawer';
// Type definitions
type RootStackParamList = {
Home: undefined;
Profile: { userId: string };
Settings: undefined;
Details: { itemId: string };
Modal: undefined;
};
type TabParamList = {
HomeTab: undefined;
SearchTab: undefined;
ProfileTab: undefined;
};
type DrawerParamList = {
HomeDrawer: undefined;
SettingsDrawer: undefined;
AboutDrawer: undefined;
};
// 1. Stack Navigation Example
const Stack = createNativeStackNavigator<RootStackParamList>();
interface HomeScreenProps {
navigation: NativeStackNavigationProp<RootStackParamList, 'Home'>;
}
const HomeScreen: React.FC<HomeScreenProps> = ({ navigation }) => {
const [items] = useState([
{ id: '1', title: 'First Item', description: 'This is the first item' },
{ id: '2', title: 'Second Item', description: 'This is the second item' },
{ id: '3', title: 'Third Item', description: 'This is the third item' },
]);
return (
<View style={styles.container}>
<Text style={styles.title}>Home Screen</Text>
<ScrollView style={styles.itemList}>
{items.map((item) => (
<TouchableOpacity
key={item.id}
style={styles.itemCard}
onPress={() => navigation.navigate('Details', { itemId: item.id })}
>
<Text style={styles.itemTitle}>{item.title}</Text>
<Text style={styles.itemDescription}>{item.description}</Text>
<Text style={styles.seeMore}>See details →</Text>
</TouchableOpacity>
))}
</ScrollView>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={() => navigation.navigate('Profile', { userId: 'user123' })}
>
<Text style={styles.buttonText}>Go to Profile</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={() => navigation.navigate('Modal')}
>
<Text style={styles.buttonText}>Open Modal</Text>
</TouchableOpacity>
</View>
</View>
);
};
interface ProfileScreenProps {
route: NativeStackScreenProps<RootStackParamList, 'Profile'>['route'];
navigation: NativeStackNavigationProp<RootStackParamList, 'Profile'>;
}
const ProfileScreen: React.FC<ProfileScreenProps> = ({ route, navigation }) => {
const { userId } = route.params;
const [user, setUser] = useState({
name: 'John Doe',
email: '[email protected]',
bio: 'Mobile app developer'
});
return (
<View style={styles.container}>
<View style={styles.profileHeader}>
<View style={styles.avatar}>
<Text style={styles.avatarText}>
{user.name.split(' ').map(n => n[0]).join('')}
</Text>
</View>
<Text style={styles.profileName}>{user.name}</Text>
<Text style={styles.profileEmail}>{user.email}</Text>
</View>
<View style={styles.profileContent}>
<Text style={styles.sectionTitle}>About</Text>
<Text style={styles.bioText}>{user.bio}</Text>
<Text style={styles.sectionTitle}>User ID</Text>
<Text style={styles.userId}>{userId}</Text>
<TouchableOpacity
style={[styles.button, styles.editButton]}
onPress={() => Alert.alert('Edit Profile', 'Profile editing coming soon!')}
>
<Text style={styles.buttonText}>Edit Profile</Text>
</TouchableOpacity>
</View>
<View style={styles.navButtons}>
<TouchableOpacity
style={[styles.navButton, styles.backButton]}
onPress={() => navigation.goBack()}
>
<Text style={styles.navButtonText}>← Back</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.navButton, styles.settingsButton]}
onPress={() => navigation.navigate('Settings')}
>
<Text style={styles.navButtonText}>Settings →</Text>
</TouchableOpacity>
</View>
</View>
);
};
const DetailsScreen: React.FC<{
route: NativeStackScreenProps<RootStackParamList, 'Details'>['route'];
navigation: NativeStackNavigationProp<RootStackParamList, 'Details'>;
}> = ({ route, navigation }) => {
const { itemId } = route.params;
const itemDetails = {
'1': { title: 'First Item', description: 'Detailed description of the first item', date: '2023-01-01' },
'2': { title: 'Second Item', description: 'Detailed description of the second item', date: '2023-01-02' },
'3': { title: 'Third Item', description: 'Detailed description of the third item', date: '2023-01-03' },
};
const item = itemDetails[itemId as keyof typeof itemDetails];
return (
<View style={styles.container}>
<Text style={styles.title}>Item Details</Text>
{item ? (
<View style={styles.detailsCard}>
<Text style={styles.detailsTitle}>{item.title}</Text>
<Text style={styles.detailsDescription}>{item.description}</Text>
<Text style={styles.detailsDate}>Created: {item.date}</Text>
<Text style={styles.itemIdText}>Item ID: {itemId}</Text>
</View>
) : (
<Text style={styles.notFound}>Item not found</Text>
)}
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={() => navigation.goBack()}
>
<Text style={styles.buttonText}>Go Back</Text>
</TouchableOpacity>
</View>
);
};
const SettingsScreen: React.FC<{
navigation: NativeStackNavigationProp<RootStackParamList, 'Settings'>;
}> = ({ navigation }) => {
const [notifications, setNotifications] = useState(true);
const [darkMode, setDarkMode] = useState(false);
return (
<View style={styles.container}>
<Text style={styles.title}>Settings</Text>
<View style={styles.settingsSection}>
<Text style={styles.sectionTitle}>Preferences</Text>
<TouchableOpacity
style={styles.settingItem}
onPress={() => setNotifications(!notifications)}
>
<Text style={styles.settingText}>Push Notifications</Text>
<View style={[styles.toggle, notifications && styles.toggleOn]}>
<Text style={styles.toggleText}>
{notifications ? 'ON' : 'OFF'}
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
style={styles.settingItem}
onPress={() => setDarkMode(!darkMode)}
>
<Text style={styles.settingText}>Dark Mode</Text>
<View style={[styles.toggle, darkMode && styles.toggleOn]}>
<Text style={styles.toggleText}>
{darkMode ? 'ON' : 'OFF'}
</Text>
</View>
</TouchableOpacity>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={[styles.button, styles.dangerButton]}
onPress={() => navigation.goBack()}
>
<Text style={styles.buttonText}>Back</Text>
</TouchableOpacity>
</View>
</View>
);
};
const ModalScreen: React.FC<{
navigation: NativeStackNavigationProp<RootStackParamList, 'Modal'>;
}> = ({ navigation }) => {
return (
<View style={styles.modalContainer}>
<View style={styles.modalContent}>
<Text style={styles.modalTitle}>Modal Screen</Text>
<Text style={styles.modalMessage}>This is a modal that can be dismissed.</Text>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={() => navigation.goBack()}
>
<Text style={styles.buttonText}>Close Modal</Text>
</TouchableOpacity>
</View>
</View>
);
};
// 2. Tab Navigation Example
const Tab = createBottomTabNavigator<TabParamList>();
const TabHomeScreen: React.FC = () => (
<View style={styles.container}>
<Text style={styles.title}>Tab Home</Text>
<Text style={styles.subtitle}>This is the home tab</Text>
</View>
);
const TabSearchScreen: React.FC = () => {
const [searchText, setSearchText] = useState('');
return (
<View style={styles.container}>
<Text style={styles.title}>Search</Text>
<TextInput
style={styles.searchInput}
placeholder="Search for something..."
value={searchText}
onChangeText={setSearchText}
/>
<Text style={styles.searchResult}>
{searchText ? `Searching for: "${searchText}"` : 'Enter search term'}
</Text>
</View>
);
};
const TabProfileScreen: React.FC = () => (
<View style={styles.container}>
<Text style={styles.title}>Tab Profile</Text>
<Text style={styles.subtitle}>This is the profile tab</Text>
</View>
);
const TabNavigator: React.FC = () => {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ color, size }) => {
let iconName = '';
if (route.name === 'HomeTab') {
iconName = '🏠';
} else if (route.name === 'SearchTab') {
iconName = '🔍';
} else if (route.name === 'ProfileTab') {
iconName = '👤';
}
return <Text style={{ fontSize: size, color }}>{iconName}</Text>;
},
tabBarActiveTintColor: '#3498db',
tabBarInactiveTintColor: '#95a5a6',
tabBarStyle: { backgroundColor: '#fff' },
})}
>
<Tab.Screen
name="HomeTab"
component={TabHomeScreen}
options={{ title: 'Home' }}
/>
<Tab.Screen
name="SearchTab"
component={TabSearchScreen}
options={{ title: 'Search' }}
/>
<Tab.Screen
name="ProfileTab"
component={TabProfileScreen}
options={{ title: 'Profile' }}
/>
</Tab.Navigator>
);
};
// 3. Complete App with Stack Navigation
const StackNavigator: React.FC = () => {
return (
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerStyle: { backgroundColor: '#3498db' },
headerTintColor: '#fff',
headerTitleStyle: { fontWeight: 'bold' },
}}
>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'React Navigation Demo' }}
/>
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={({ route }) => ({ title: `Profile - ${route.params.userId}` })}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{ title: 'Item Details' }}
/>
<Stack.Screen
name="Settings"
component={SettingsScreen}
options={{ title: 'Settings' }}
/>
<Stack.Screen
name="Modal"
component={ModalScreen}
options={{
presentation: 'modal',
title: 'Modal',
headerShown: false,
}}
/>
</Stack.Navigator>
);
};
// 4. Main App Component
const NavigationApp: React.FC = () => {
const [useTabs, setUseTabs] = useState(false);
return (
<NavigationContainer>
{useTabs ? (
<View style={styles.container}>
<View style={styles.navigationToggle}>
<TouchableOpacity
style={[styles.toggleButton, useTabs && styles.activeToggle]}
onPress={() => setUseTabs(true)}
>
<Text style={styles.toggleButtonText}>Tabs</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.toggleButton, !useTabs && styles.activeToggle]}
onPress={() => setUseTabs(false)}
>
<Text style={styles.toggleButtonText}>Stack</Text>
</TouchableOpacity>
</View>
<TabNavigator />
</View>
) : (
<View style={styles.container}>
<View style={styles.navigationToggle}>
<TouchableOpacity
style={[styles.toggleButton, useTabs && styles.activeToggle]}
onPress={() => setUseTabs(true)}
>
<Text style={styles.toggleButtonText}>Tabs</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.toggleButton, !useTabs && styles.activeToggle]}
onPress={() => setUseTabs(false)}
>
<Text style={styles.toggleButtonText}>Stack</Text>
</TouchableOpacity>
</View>
<StackNavigator />
</View>
)}
</NavigationContainer>
);
};
// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8f9fa',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#2c3e50',
textAlign: 'center',
margin: 20,
},
subtitle: {
fontSize: 16,
color: '#7f8c8d',
textAlign: 'center',
marginBottom: 20,
},
itemList: {
flex: 1,
marginHorizontal: 20,
},
itemCard: {
backgroundColor: '#fff',
padding: 16,
marginBottom: 12,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
itemTitle: {
fontSize: 18,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 4,
},
itemDescription: {
fontSize: 14,
color: '#7f8c8d',
marginBottom: 8,
},
seeMore: {
fontSize: 12,
color: '#3498db',
textAlign: 'right',
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 20,
},
button: {
paddingHorizontal: 20,
paddingVertical: 12,
borderRadius: 8,
alignItems: 'center',
minWidth: 120,
},
primaryButton: {
backgroundColor: '#3498db',
},
secondaryButton: {
backgroundColor: '#95a5a6',
},
dangerButton: {
backgroundColor: '#e74c3c',
},
editButton: {
backgroundColor: '#f39c12',
},
buttonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
profileHeader: {
alignItems: 'center',
marginBottom: 30,
},
avatar: {
width: 80,
height: 80,
borderRadius: 40,
backgroundColor: '#3498db',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 16,
},
avatarText: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
},
profileName: {
fontSize: 20,
fontWeight: 'bold',
color: '#2c3e50',
marginBottom: 4,
},
profileEmail: {
fontSize: 14,
color: '#7f8c8d',
},
profileContent: {
paddingHorizontal: 20,
},
sectionTitle: {
fontSize: 18,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 8,
},
bioText: {
fontSize: 16,
color: '#34495e',
marginBottom: 20,
},
userId: {
fontSize: 14,
color: '#7f8c8d',
marginBottom: 20,
},
navButtons: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 20,
marginTop: 20,
},
navButton: {
paddingHorizontal: 20,
paddingVertical: 12,
borderRadius: 8,
},
backButton: {
backgroundColor: '#95a5a6',
},
settingsButton: {
backgroundColor: '#f39c12',
},
navButtonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
detailsCard: {
backgroundColor: '#fff',
padding: 20,
margin: 20,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
detailsTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#2c3e50',
marginBottom: 8,
},
detailsDescription: {
fontSize: 16,
color: '#34495e',
marginBottom: 12,
},
detailsDate: {
fontSize: 14,
color: '#7f8c8d',
marginBottom: 8,
},
itemIdText: {
fontSize: 12,
color: '#95a5a6',
},
notFound: {
fontSize: 16,
color: '#e74c3c',
textAlign: 'center',
margin: 20,
},
settingsSection: {
margin: 20,
},
settingItem: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 16,
borderBottomWidth: 1,
borderBottomColor: '#ecf0f1',
},
settingText: {
fontSize: 16,
color: '#2c3e50',
},
toggle: {
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: 12,
backgroundColor: '#ecf0f1',
},
toggleOn: {
backgroundColor: '#27ae60',
},
toggleText: {
fontSize: 12,
fontWeight: '600',
color: '#7f8c8d',
},
toggleOnText: {
color: '#fff',
},
modalContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
modalContent: {
backgroundColor: '#fff',
padding: 30,
borderRadius: 12,
alignItems: 'center',
margin: 20,
},
modalTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#2c3e50',
marginBottom: 12,
},
modalMessage: {
fontSize: 16,
color: '#7f8c8d',
textAlign: 'center',
marginBottom: 20,
},
searchInput: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
padding: 12,
fontSize: 16,
margin: 20,
},
searchResult: {
fontSize: 16,
color: '#7f8c8d',
textAlign: 'center',
marginHorizontal: 20,
},
navigationToggle: {
flexDirection: 'row',
backgroundColor: '#34495e',
padding: 4,
},
toggleButton: {
flex: 1,
paddingVertical: 12,
alignItems: 'center',
borderRadius: 4,
},
activeToggle: {
backgroundColor: '#3498db',
},
toggleButtonText: {
color: '#ecf0f1',
fontSize: 14,
fontWeight: '500',
},
});
export default NavigationApp;
💻 React Native State Management typescript
🟡 intermediate
State management patterns in React Native including Redux, Context API, and React Query
// React Native State Management Examples
import React, { useState, useContext, createContext, useReducer, useEffect } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
TextInput,
ScrollView,
Alert,
ActivityIndicator
} from 'react-native';
// 1. useState and Local State Management
const LocalStateExample: React.FC = () => {
const [user, setUser] = useState({
name: '',
email: '',
age: '',
});
const [errors, setErrors] = useState<Record<string, string>>({});
const [isSubmitting, setIsSubmitting] = useState(false);
const validateForm = () => {
const newErrors: Record<string, string> = {};
if (!user.name.trim()) {
newErrors.name = 'Name is required';
}
if (!user.email.trim()) {
newErrors.email = 'Email is required';
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(user.email)) {
newErrors.email = 'Please enter a valid email';
}
if (!user.age.trim()) {
newErrors.age = 'Age is required';
} else if (parseInt(user.age) < 18) {
newErrors.age = 'You must be at least 18 years old';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = async () => {
if (!validateForm()) return;
setIsSubmitting(true);
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 2000));
Alert.alert('Success', 'Form submitted successfully!');
setIsSubmitting(false);
};
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Local State Management</Text>
<View style={styles.inputGroup}>
<Text style={styles.label}>Name</Text>
<TextInput
style={[styles.input, errors.name && styles.inputError]}
value={user.name}
onChangeText={(text) => setUser({ ...user, name: text })}
placeholder="Enter your name"
/>
{errors.name && <Text style={styles.errorText}>{errors.name}</Text>}
</View>
<View style={styles.inputGroup}>
<Text style={styles.label}>Email</Text>
<TextInput
style={[styles.input, errors.email && styles.inputError]}
value={user.email}
onChangeText={(text) => setUser({ ...user, email: text })}
placeholder="Enter your email"
keyboardType="email-address"
/>
{errors.email && <Text style={styles.errorText}>{errors.email}</Text>}
</View>
<View style={styles.inputGroup}>
<Text style={styles.label}>Age</Text>
<TextInput
style={[styles.input, errors.age && styles.inputError]}
value={user.age}
onChangeText={(text) => setUser({ ...user, age: text })}
placeholder="Enter your age"
keyboardType="numeric"
/>
{errors.age && <Text style={styles.errorText}>{errors.age}</Text>}
</View>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={handleSubmit}
disabled={isSubmitting}
>
{isSubmitting ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>Submit</Text>
)}
</TouchableOpacity>
<View style={styles.debugInfo}>
<Text style={styles.debugTitle}>Current State:</Text>
<Text style={styles.debugText}>{JSON.stringify(user, null, 2)}</Text>
</View>
</View>
);
};
// 2. Context API for Global State
interface AppState {
theme: 'light' | 'dark';
user: User | null;
notifications: Notification[];
}
interface User {
id: string;
name: string;
email: string;
}
interface Notification {
id: string;
message: string;
timestamp: Date;
}
interface AppContextType {
state: AppState;
setTheme: (theme: 'light' | 'dark') => void;
setUser: (user: User | null) => void;
addNotification: (message: string) => void;
clearNotifications: () => void;
}
const AppContext = createContext<AppContextType | null>(null);
export const useAppContext = () => {
const context = useContext(AppContext);
if (!context) {
throw new Error('useAppContext must be used within an AppProvider');
}
return context;
};
const AppProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [state, setState] = useState<AppState>({
theme: 'light',
user: null,
notifications: [],
});
const setTheme = (theme: 'light' | 'dark') => {
setState(prev => ({ ...prev, theme }));
};
const setUser = (user: User | null) => {
setState(prev => ({ ...prev, user }));
};
const addNotification = (message: string) => {
const notification: Notification = {
id: Date.now().toString(),
message,
timestamp: new Date(),
};
setState(prev => ({
...prev,
notifications: [notification, ...prev.notifications].slice(0, 5),
}));
};
const clearNotifications = () => {
setState(prev => ({ ...prev, notifications: [] }));
};
return (
<AppContext.Provider value={{
state,
setTheme,
setUser,
addNotification,
clearNotifications,
}}>
{children}
</AppContext.Provider>
);
};
const ThemeToggle: React.FC = () => {
const { state, setTheme } = useAppContext();
return (
<TouchableOpacity
style={[
styles.themeToggle,
state.theme === 'dark' && styles.themeToggleDark
]}
onPress={() => setTheme(state.theme === 'light' ? 'dark' : 'light')}
>
<Text style={styles.themeToggleText}>
{state.theme === 'light' ? '🌞' : '🌙'} {state.theme === 'light' ? 'Light' : 'Dark'}
</Text>
</TouchableOpacity>
);
};
const UserProfile: React.FC = () => {
const { state, setUser } = useAppContext();
const handleLogin = () => {
const user: User = {
id: '1',
name: 'John Doe',
email: '[email protected]',
};
setUser(user);
};
const handleLogout = () => {
setUser(null);
};
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>User Profile</Text>
{state.user ? (
<View>
<Text style={styles.userInfo}>Name: {state.user.name}</Text>
<Text style={styles.userInfo}>Email: {state.user.email}</Text>
<Text style={styles.userInfo}>ID: {state.user.id}</Text>
<TouchableOpacity
style={[styles.button, styles.dangerButton]}
onPress={handleLogout}
>
<Text style={styles.buttonText}>Logout</Text>
</TouchableOpacity>
</View>
) : (
<View>
<Text style={styles.placeholderText}>Not logged in</Text>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={handleLogin}
>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
</View>
)}
</View>
);
};
const NotificationPanel: React.FC = () => {
const { state, addNotification, clearNotifications } = useAppContext();
const handleAddNotification = () => {
const messages = [
'New message received',
'Your profile was updated',
'System maintenance scheduled',
'New feature available',
];
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
addNotification(randomMessage);
};
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Notifications</Text>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={handleAddNotification}
>
<Text style={styles.buttonText}>Add Notification</Text>
</TouchableOpacity>
{state.notifications.length > 0 && (
<TouchableOpacity
style={[styles.button, styles.clearButton]}
onPress={clearNotifications}
>
<Text style={styles.buttonText}>Clear All</Text>
</TouchableOpacity>
)}
<ScrollView style={styles.notificationList}>
{state.notifications.map((notification) => (
<View key={notification.id} style={styles.notificationItem}>
<Text style={styles.notificationText}>{notification.message}</Text>
<Text style={styles.notificationTime}>
{notification.timestamp.toLocaleTimeString()}
</Text>
</View>
))}
</ScrollView>
{state.notifications.length === 0 && (
<Text style={styles.placeholderText}>No notifications</Text>
)}
</View>
);
};
// 3. useReducer for Complex State
interface Todo {
id: string;
text: string;
completed: boolean;
createdAt: Date;
}
type TodoAction =
| { type: 'ADD_TODO'; text: string }
| { type: 'TOGGLE_TODO'; id: string }
| { type: 'DELETE_TODO'; id: string }
| { type: 'EDIT_TODO'; id: string; text: string }
| { type: 'CLEAR_COMPLETED' };
const todoReducer = (state: Todo[], action: TodoAction): Todo[] => {
switch (action.type) {
case 'ADD_TODO':
return [
{
id: Date.now().toString(),
text: action.text,
completed: false,
createdAt: new Date(),
},
...state,
];
case 'TOGGLE_TODO':
return state.map((todo) =>
todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
);
case 'DELETE_TODO':
return state.filter((todo) => todo.id !== action.id);
case 'EDIT_TODO':
return state.map((todo) =>
todo.id === action.id ? { ...todo, text: action.text } : todo
);
case 'CLEAR_COMPLETED':
return state.filter((todo) => !todo.completed);
default:
return state;
}
};
const TodoReducerExample: React.FC = () => {
const [todos, dispatch] = useReducer(todoReducer, []);
const [newTodoText, setNewTodoText] = useState('');
const addTodo = () => {
if (newTodoText.trim()) {
dispatch({ type: 'ADD_TODO', text: newTodoText.trim() });
setNewTodoText('');
}
};
const toggleTodo = (id: string) => {
dispatch({ type: 'TOGGLE_TODO', id });
};
const deleteTodo = (id: string) => {
Alert.alert(
'Delete Todo',
'Are you sure you want to delete this todo?',
[
{ text: 'Cancel', style: 'cancel' },
{ text: 'Delete', style: 'destructive', onPress: () => dispatch({ type: 'DELETE_TODO', id }) }
]
);
};
const editTodo = (id: string, currentText: string) => {
Alert.prompt(
'Edit Todo',
'Edit your todo:',
[
{ text: 'Cancel', style: 'cancel' },
{
text: 'Save',
onPress: (newText) => {
if (newText && newText.trim()) {
dispatch({ type: 'EDIT_TODO', id, text: newText.trim() });
}
},
},
],
'plain-text',
currentText
);
};
const completedCount = todos.filter(todo => todo.completed).length;
const activeCount = todos.filter(todo => !todo.completed).length;
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>useReducer Todo App</Text>
<View style={styles.inputGroup}>
<TextInput
style={styles.input}
value={newTodoText}
onChangeText={setNewTodoText}
placeholder="What needs to be done?"
onSubmitEditing={addTodo}
/>
<TouchableOpacity style={[styles.button, styles.addButton]} onPress={addTodo}>
<Text style={styles.addButtonText}>+</Text>
</TouchableOpacity>
</View>
<View style={styles.statsContainer}>
<Text style={styles.statText}>
{activeCount} active, {completedCount} completed
</Text>
{completedCount > 0 && (
<TouchableOpacity
style={[styles.button, styles.clearButton]}
onPress={() => dispatch({ type: 'CLEAR_COMPLETED' })}
>
<Text style={styles.buttonTextSmall}>Clear Completed</Text>
</TouchableOpacity>
)}
</View>
<ScrollView style={styles.todoList}>
{todos.map((todo) => (
<View key={todo.id} style={styles.todoItem}>
<TouchableOpacity
style={styles.todoCheckbox}
onPress={() => toggleTodo(todo.id)}
>
<View style={[styles.checkbox, todo.completed && styles.checkboxChecked]}>
{todo.completed && <Text style={styles.checkmark}>✓</Text>}
</View>
</TouchableOpacity>
<View style={styles.todoContent}>
<TouchableOpacity
style={styles.todoTextContainer}
onPress={() => editTodo(todo.id, todo.text)}
>
<Text style={[styles.todoText, todo.completed && styles.todoTextCompleted]}>
{todo.text}
</Text>
</TouchableOpacity>
<Text style={styles.todoDate}>
{todo.createdAt.toLocaleDateString()}
</Text>
</View>
<TouchableOpacity
style={styles.deleteButton}
onPress={() => deleteTodo(todo.id)}
>
<Text style={styles.deleteButtonText}>×</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
{todos.length === 0 && (
<Text style={styles.placeholderText}>No todos yet. Add one above!</Text>
)}
<View style={styles.debugInfo}>
<Text style={styles.debugTitle}>State (useReducer):</Text>
<Text style={styles.debugText}>{JSON.stringify(todos.slice(0, 2), null, 2)}</Text>
{todos.length > 2 && <Text style={styles.debugText}>...and {todos.length - 2} more items</Text>}
</View>
</View>
);
};
// 4. Custom Hook for Data Fetching
interface UseDataResult<T> {
data: T | null;
loading: boolean;
error: string | null;
refetch: () => void;
}
function useData<T>(fetchFunction: () => Promise<T>): UseDataResult<T> {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetchData = async () => {
setLoading(true);
setError(null);
try {
const result = await fetchFunction();
setData(result);
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData();
}, []);
return { data, loading, error, refetch: fetchData };
}
// API simulation functions
const fetchUser = async (): Promise<User> => {
await new Promise(resolve => setTimeout(resolve, 1500));
return {
id: '1',
name: 'Jane Smith',
email: '[email protected]',
};
};
const fetchPosts = async (): Promise<Array<{ id: string; title: string; body: string }>> => {
await new Promise(resolve => setTimeout(resolve, 2000));
return [
{ id: '1', title: 'First Post', body: 'This is the first post' },
{ id: '2', title: 'Second Post', body: 'This is the second post' },
{ id: '3', title: 'Third Post', body: 'This is the third post' },
];
};
const DataFetchingExample: React.FC = () => {
const { data: user, loading: userLoading, error: userError, refetch: refetchUser } = useData(fetchUser);
const { data: posts, loading: postsLoading, error: postsError, refetch: refetchPosts } = useData(fetchPosts);
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Custom Hook Data Fetching</Text>
<View style={styles.section}>
<Text style={styles.sectionTitle}>User Data</Text>
{userLoading && <ActivityIndicator color="#3498db" />}
{userError && <Text style={styles.errorText}>Error: {userError}</Text>}
{user && (
<View style={styles.dataDisplay}>
<Text style={styles.dataLabel}>Name: {user.name}</Text>
<Text style={styles.dataLabel}>Email: {user.email}</Text>
</View>
)}
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={refetchUser}
disabled={userLoading}
>
<Text style={styles.buttonText}>Refresh User</Text>
</TouchableOpacity>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Posts Data</Text>
{postsLoading && <ActivityIndicator color="#3498db" />}
{postsError && <Text style={styles.errorText}>Error: {postsError}</Text>}
{posts && (
<ScrollView style={styles.dataList}>
{posts.map((post) => (
<View key={post.id} style={styles.postItem}>
<Text style={styles.postTitle}>{post.title}</Text>
<Text style={styles.postBody}>{post.body}</Text>
</View>
))}
</ScrollView>
)}
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={refetchPosts}
disabled={postsLoading}
>
<Text style={styles.buttonText}>Refresh Posts</Text>
</TouchableOpacity>
</View>
</View>
);
};
// 5. Main App Component with Context Provider
const StateManagementApp: React.FC = () => {
return (
<AppProvider>
<ScrollView style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerTitle}>State Management Examples</Text>
<ThemeToggle />
</View>
<LocalStateExample />
<UserProfile />
<NotificationPanel />
<TodoReducerExample />
<DataFetchingExample />
</ScrollView>
</AppProvider>
);
};
// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8f9fa',
},
header: {
padding: 20,
backgroundColor: '#3498db',
alignItems: 'center',
},
headerTitle: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
marginBottom: 16,
textAlign: 'center',
},
themeToggle: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#ecf0f1',
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
},
themeToggleDark: {
backgroundColor: '#34495e',
},
themeToggleText: {
fontSize: 16,
fontWeight: '500',
},
card: {
backgroundColor: '#fff',
margin: 16,
padding: 20,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
cardTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#2c3e50',
marginBottom: 16,
textAlign: 'center',
},
inputGroup: {
marginBottom: 16,
},
label: {
fontSize: 16,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 8,
},
input: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 6,
padding: 12,
fontSize: 16,
backgroundColor: '#fff',
},
inputError: {
borderColor: '#e74c3c',
},
errorText: {
color: '#e74c3c',
fontSize: 14,
marginTop: 4,
},
button: {
paddingVertical: 12,
paddingHorizontal: 20,
borderRadius: 6,
alignItems: 'center',
marginTop: 8,
},
primaryButton: {
backgroundColor: '#3498db',
},
secondaryButton: {
backgroundColor: '#95a5a6',
},
dangerButton: {
backgroundColor: '#e74c3c',
},
clearButton: {
backgroundColor: '#f39c12',
},
addButton: {
backgroundColor: '#27ae60',
width: 48,
height: 48,
borderRadius: 6,
justifyContent: 'center',
alignItems: 'center',
marginLeft: 8,
},
addButtonText: {
color: '#fff',
fontSize: 24,
fontWeight: 'bold',
},
buttonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
buttonTextSmall: {
color: '#fff',
fontSize: 14,
fontWeight: '600',
},
userInfo: {
fontSize: 16,
color: '#2c3e50',
marginBottom: 8,
},
placeholderText: {
fontSize: 16,
color: '#7f8c8d',
textAlign: 'center',
marginVertical: 16,
},
debugInfo: {
marginTop: 20,
padding: 12,
backgroundColor: '#2c3e50',
borderRadius: 6,
},
debugTitle: {
fontSize: 14,
fontWeight: '600',
color: '#ecf0f1',
marginBottom: 8,
},
debugText: {
fontSize: 12,
color: '#bdc3c7',
fontFamily: 'monospace',
},
notificationList: {
maxHeight: 200,
marginTop: 16,
},
notificationItem: {
backgroundColor: '#ecf0f1',
padding: 12,
marginBottom: 8,
borderRadius: 6,
borderLeftWidth: 4,
borderLeftColor: '#3498db',
},
notificationText: {
fontSize: 14,
color: '#2c3e50',
marginBottom: 4,
},
notificationTime: {
fontSize: 12,
color: '#7f8c8d',
},
statsContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 8,
marginBottom: 16,
},
statText: {
fontSize: 14,
color: '#7f8c8d',
},
todoList: {
maxHeight: 300,
},
todoItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 8,
borderBottomWidth: 1,
borderBottomColor: '#ecf0f1',
},
todoCheckbox: {
marginRight: 12,
},
checkbox: {
width: 24,
height: 24,
borderWidth: 2,
borderColor: '#ddd',
borderRadius: 4,
justifyContent: 'center',
alignItems: 'center',
},
checkboxChecked: {
backgroundColor: '#27ae60',
borderColor: '#27ae60',
},
checkmark: {
color: '#fff',
fontSize: 16,
fontWeight: 'bold',
},
todoContent: {
flex: 1,
},
todoTextContainer: {
flex: 1,
},
todoText: {
fontSize: 16,
color: '#2c3e50',
},
todoTextCompleted: {
textDecorationLine: 'line-through',
color: '#7f8c8d',
},
todoDate: {
fontSize: 12,
color: '#95a5a6',
marginTop: 2,
},
deleteButton: {
padding: 8,
backgroundColor: '#e74c3c',
borderRadius: 4,
marginLeft: 8,
},
deleteButtonText: {
color: '#fff',
fontSize: 16,
fontWeight: 'bold',
},
section: {
marginBottom: 24,
},
sectionTitle: {
fontSize: 16,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 12,
},
dataDisplay: {
backgroundColor: '#f8f9fa',
padding: 12,
borderRadius: 6,
marginBottom: 12,
},
dataLabel: {
fontSize: 16,
color: '#2c3e50',
marginBottom: 4,
},
dataList: {
maxHeight: 200,
marginBottom: 12,
},
postItem: {
backgroundColor: '#f8f9fa',
padding: 12,
marginBottom: 8,
borderRadius: 6,
},
postTitle: {
fontSize: 16,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 4,
},
postBody: {
fontSize: 14,
color: '#7f8c8d',
},
});
export default StateManagementApp;
💻 React Native Native Integration typescript
🔴 complex
Native module integration, platform-specific code, and bridging React Native with native APIs
// React Native Native Integration Examples
import React, { useState, useEffect, useRef } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
ScrollView,
Alert,
NativeModules,
Platform,
PermissionsAndroid,
Linking,
Share,
Dimensions,
AppState,
DeviceEventEmitter
} from 'react-native';
import { CameraRoll } from '@react-native-community/cameraroll';
import Geolocation from '@react-native-community/geolocation';
// 1. Platform-specific code
const PlatformSpecificExample: React.FC = () => {
const [platformInfo, setPlatformInfo] = useState({});
useEffect(() => {
setPlatformInfo({
os: Platform.OS,
version: Platform.Version,
isPad: Platform.isPad,
isTVOS: Platform.isTVOS,
constants: Platform.constants,
});
}, []);
const handlePlatformAction = () => {
if (Platform.OS === 'ios') {
Alert.alert('iOS Feature', 'This is an iOS-specific feature');
} else if (Platform.OS === 'android') {
Alert.alert('Android Feature', 'This is an Android-specific feature');
}
};
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Platform-Specific Code</Text>
<View style={styles.platformInfo}>
<Text style={styles.infoLabel}>Platform: {Platform.OS}</Text>
<Text style={styles.infoLabel}>Version: {Platform.Version}</Text>
{Platform.OS === 'ios' && (
<>
<Text style={styles.infoLabel}>Is iPad: {Platform.isPad ? 'Yes' : 'No'}</Text>
<Text style={styles.infoLabel}>Is TV: {Platform.isTVOS ? 'Yes' : 'No'}</Text>
</>
)}
</View>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={handlePlatformAction}
>
<Text style={styles.buttonText}>
{Platform.OS === 'ios' ? 'iOS Action' : 'Android Action'}
</Text>
</TouchableOpacity>
<View style={styles.platformSpecificUI}>
{Platform.OS === 'ios' ? (
<View style={styles.iosUI}>
<Text style={styles.iosLabel}>iOS UI Elements</Text>
<View style={styles.iosButton}>
<Text style={styles.iosButtonText}>iOS Button</Text>
</View>
</View>
) : (
<View style={styles.androidUI}>
<Text style={styles.androidLabel}>Android UI Elements</Text>
<View style={styles.androidButton}>
<Text style={styles.androidButtonText}>Android Button</Text>
</View>
</View>
)}
</View>
</View>
);
};
// 2. Device APIs Integration
const DeviceAPIsExample: React.FC = () => {
const [location, setLocation] = useState(null);
const [dimensions, setDimensions] = useState(Dimensions.get('window'));
const [appState, setAppState] = useState(AppState.currentState);
const [shareContent, setShareContent] = useState('Check out this React Native app!');
useEffect(() => {
const dimensionHandler = ({ window }) => setDimensions(window);
const subscription = Dimensions.addEventListener('change', dimensionHandler);
const appStateHandler = (nextAppState) => setAppState(nextAppState);
const appStateSubscription = AppState.addEventListener('change', appStateHandler);
return () => {
subscription?.remove();
appStateSubscription?.remove();
};
}, []);
const getCurrentLocation = () => {
Geolocation.getCurrentPosition(
(position) => {
setLocation({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
});
},
(error) => {
Alert.alert('Error', 'Unable to get location');
},
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
};
const watchLocation = () => {
const watchId = Geolocation.watchPosition(
(position) => {
setLocation({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
accuracy: position.coords.accuracy,
});
},
(error) => {
Alert.alert('Error', 'Unable to watch location');
},
{ enableHighAccuracy: true, distanceFilter: 10 }
);
Alert.alert('Watching Location', 'Location updates started');
};
const shareContentAction = async () => {
try {
await Share.share({
message: shareContent,
url: 'https://reactnative.dev',
});
} catch (error) {
Alert.alert('Error', 'Unable to share content');
}
};
const openExternalApp = async () => {
const url = 'https://reactnative.dev';
const supported = await Linking.canOpenURL(url);
if (supported) {
await Linking.openURL(url);
} else {
Alert.alert('Error', 'Unable to open URL');
}
};
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Device APIs Integration</Text>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Screen Dimensions</Text>
<Text style={styles.infoLabel}>Width: {dimensions.width}</Text>
<Text style={styles.infoLabel}>Height: {dimensions.height}</Text>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>App State: {appState}</Text>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Location Services</Text>
{location ? (
<View style={styles.locationInfo}>
<Text style={styles.infoLabel}>Latitude: {location.latitude}</Text>
<Text style={styles.infoLabel}>Longitude: {location.longitude}</Text>
{location.accuracy && (
<Text style={styles.infoLabel}>Accuracy: {location.accuracy}m</Text>
)}
</View>
) : (
<Text style={styles.placeholderText}>No location data</Text>
)}
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={getCurrentLocation}
>
<Text style={styles.buttonText}>Get Current Location</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={watchLocation}
>
<Text style={styles.buttonText}>Watch Location</Text>
</TouchableOpacity>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>External Integration</Text>
<View style={styles.shareContainer}>
<TextInput
style={styles.shareInput}
value={shareContent}
onChangeText={setShareContent}
placeholder="Enter content to share"
/>
<TouchableOpacity
style={[styles.button, styles.shareButton]}
onPress={shareContentAction}
>
<Text style={styles.buttonText}>Share</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={openExternalApp}
>
<Text style={styles.buttonText}>Open React Native Website</Text>
</TouchableOpacity>
</View>
</View>
);
};
// 3. Permissions Management
const PermissionsExample: React.FC = () => {
const [permissions, setPermissions] = useState({});
const requestLocationPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Permission',
message: 'This app needs access to your location',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
}
);
setPermissions(prev => ({
...prev,
location: granted === PermissionsAndroid.RESULTS.GRANTED,
}));
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
Alert.alert('Success', 'Location permission granted');
} else {
Alert.alert('Error', 'Location permission denied');
}
} catch (err) {
Alert.alert('Error', 'Unable to request location permission');
}
} else {
Alert.alert('Info', 'Location permissions are handled differently on iOS');
}
};
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message: 'This app needs access to your camera',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
}
);
setPermissions(prev => ({
...prev,
camera: granted === PermissionsAndroid.RESULTS.GRANTED,
}));
Alert.alert(
'Camera Permission',
granted === PermissionsAndroid.RESULTS.GRANTED ? 'Granted' : 'Denied'
);
} catch (err) {
Alert.alert('Error', 'Unable to request camera permission');
}
} else {
Alert.alert('Info', 'Camera permissions are handled differently on iOS');
}
};
const checkPermission = async (permission: string) => {
if (Platform.OS === 'android') {
try {
const hasPermission = await PermissionsAndroid.check(permission);
Alert.alert('Permission Status', hasPermission ? 'Granted' : 'Not Granted');
} catch (err) {
Alert.alert('Error', 'Unable to check permission');
}
}
};
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Permissions Management</Text>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Location Permission</Text>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={requestLocationPermission}
>
<Text style={styles.buttonText}>Request Location Permission</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={() => checkPermission(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION)}
>
<Text style={styles.buttonText}>Check Location Permission</Text>
</TouchableOpacity>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Camera Permission</Text>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={requestCameraPermission}
>
<Text style={styles.buttonText}>Request Camera Permission</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={() => checkPermission(PermissionsAndroid.PERMISSIONS.CAMERA)}
>
<Text style={styles.buttonText}>Check Camera Permission</Text>
</TouchableOpacity>
</View>
<View style={styles.permissionsStatus}>
<Text style={styles.sectionTitle}>Current Permissions Status</Text>
{Object.entries(permissions).map(([key, value]) => (
<Text key={key} style={styles.infoLabel}>
{key}: {value ? '✓ Granted' : '✗ Denied'}
</Text>
))}
</View>
</View>
);
};
// 4. Native Module Example (Simulation)
const NativeModuleExample: React.FC = () => {
const [batteryLevel, setBatteryLevel] = useState(null);
const [deviceInfo, setDeviceInfo] = useState({});
// Simulating native module calls
const getBatteryLevel = async () => {
// This would normally call a native module
// For example: const level = await NativeModules.Battery.getLevel();
// Simulate battery level
const simulatedLevel = Math.random() * 100;
setBatteryLevel(simulatedLevel.toFixed(1));
Alert.alert('Battery Level', `Current battery: ${simulatedLevel.toFixed(1)}%`);
};
const getDeviceInfo = async () => {
// This would normally call a native module
// For example: const info = await NativeModules.DeviceInfo.getInfo();
const simulatedInfo = {
model: Platform.OS === 'ios' ? 'iPhone Simulator' : 'Android Emulator',
brand: Platform.OS === 'ios' ? 'Apple' : 'Google',
systemVersion: Platform.Version,
};
setDeviceInfo(simulatedInfo);
};
const showAlert = (title: string, message: string) => {
// This would normally call a native module for custom alerts
Alert.alert(title, message);
};
const vibrateDevice = () => {
// This would normally call a native module
// For example: NativeModules.Vibration.vibrate(1000);
Alert.alert('Vibration', 'Device would vibrate for 1 second');
};
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Native Module Integration</Text>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Battery Information</Text>
{batteryLevel !== null && (
<Text style={styles.infoLabel}>
Battery Level: {batteryLevel}%
</Text>
)}
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={getBatteryLevel}
>
<Text style={styles.buttonText}>Get Battery Level</Text>
</TouchableOpacity>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Device Information</Text>
{Object.keys(deviceInfo).length > 0 ? (
<View style={styles.deviceInfo}>
<Text style={styles.infoLabel}>Model: {deviceInfo.model}</Text>
<Text style={styles.infoLabel}>Brand: {deviceInfo.brand}</Text>
<Text style={styles.infoLabel}>OS Version: {deviceInfo.systemVersion}</Text>
</View>
) : (
<Text style={styles.placeholderText}>No device info available</Text>
)}
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={getDeviceInfo}
>
<Text style={styles.buttonText}>Get Device Info</Text>
</TouchableOpacity>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Native Actions</Text>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={() => showAlert('Custom Alert', 'This is a custom native alert')}
>
<Text style={styles.buttonText}>Show Native Alert</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={vibrateDevice}
>
<Text style={styles.buttonText}>Vibrate Device</Text>
</TouchableOpacity>
</View>
<View style={styles.nativeModuleInfo}>
<Text style={styles.infoLabel}>
Note: These examples simulate native module calls.
In a real app, you would create custom native modules
for iOS (Swift/Objective-C) and Android (Java/Kotlin).
</Text>
</View>
</View>
);
};
// 5. Event Emitter and Device Events
const EventEmitterExample: React.FC = () => {
const [events, setEvents] = useState([]);
const [isListening, setIsListening] = useState(false);
const eventListenerRef = useRef(null);
const addEvent = (eventName: string, data: any) => {
const newEvent = {
id: Date.now(),
name: eventName,
data: JSON.stringify(data),
timestamp: new Date().toLocaleTimeString(),
};
setEvents(prev => [newEvent, ...prev].slice(0, 10));
};
const startListening = () => {
if (!isListening) {
// Listen to app state changes
eventListenerRef.current = AppState.addEventListener('change', (nextAppState) => {
addEvent('App State Change', { state: nextAppState });
});
// Listen to memory warnings (iOS only)
if (Platform.OS === 'ios') {
// This would normally be implemented as a native module
console.log('Memory warning listener would be set up here');
}
setIsListening(true);
addEvent('Event Listener Started', { status: 'active' });
}
};
const stopListening = () => {
if (eventListenerRef.current) {
eventListenerRef.current.remove();
eventListenerRef.current = null;
}
setIsListening(false);
addEvent('Event Listener Stopped', { status: 'inactive' });
};
const emitCustomEvent = () => {
// Emit a custom event
DeviceEventEmitter.emit('customEvent', {
message: 'Hello from custom event!',
timestamp: Date.now(),
});
addEvent('Custom Event Emitted', { type: 'customEvent' });
};
const simulateMemoryWarning = () => {
if (Platform.OS === 'ios') {
// Simulate memory warning event
addEvent('Memory Warning', { level: 'high' });
} else {
addEvent('Low Memory', { available: '45MB' });
}
};
useEffect(() => {
// Listen for custom events
const customEventSubscription = DeviceEventEmitter.addListener('customEvent', (event) => {
addEvent('Custom Event Received', event);
});
return () => {
customEventSubscription.remove();
};
}, []);
return (
<View style={styles.card}>
<Text style={styles.cardTitle}>Event Emitter & Device Events</Text>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Event Listener Status</Text>
<View style={styles.statusContainer}>
<Text style={styles.statusText}>
Status: {isListening ? '🟢 Listening' : '🔴 Not Listening'}
</Text>
<TouchableOpacity
style={[
styles.button,
isListening ? styles.dangerButton : styles.primaryButton
]}
onPress={isListening ? stopListening : startListening}
>
<Text style={styles.buttonText}>
{isListening ? 'Stop Listening' : 'Start Listening'}
</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Event Actions</Text>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={emitCustomEvent}
>
<Text style={styles.buttonText}>Emit Custom Event</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.secondaryButton]}
onPress={simulateMemoryWarning}
>
<Text style={styles.buttonText}>
{Platform.OS === 'ios' ? 'Simulate Memory Warning' : 'Simulate Low Memory'}
</Text>
</TouchableOpacity>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Event Log</Text>
<ScrollView style={styles.eventLog}>
{events.map((event) => (
<View key={event.id} style={styles.eventItem}>
<Text style={styles.eventName}>{event.name}</Text>
<Text style={styles.eventData}>{event.data}</Text>
<Text style={styles.eventTime}>{event.timestamp}</Text>
</View>
))}
{events.length === 0 && (
<Text style={styles.placeholderText}>No events logged yet</Text>
)}
</ScrollView>
</View>
</View>
);
};
// Main App Component
const NativeIntegrationApp: React.FC = () => {
return (
<ScrollView style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerTitle}>React Native Integration</Text>
<Text style={styles.headerSubtitle}>Platform-specific features and native APIs</Text>
</View>
<PlatformSpecificExample />
<DeviceAPIsExample />
<PermissionsExample />
<NativeModuleExample />
<EventEmitterExample />
</ScrollView>
);
};
// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8f9fa',
},
header: {
padding: 20,
backgroundColor: '#2c3e50',
alignItems: 'center',
},
headerTitle: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
marginBottom: 8,
},
headerSubtitle: {
fontSize: 16,
color: '#ecf0f1',
textAlign: 'center',
},
card: {
backgroundColor: '#fff',
margin: 16,
padding: 20,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
cardTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#2c3e50',
marginBottom: 16,
textAlign: 'center',
},
section: {
marginBottom: 20,
},
sectionTitle: {
fontSize: 16,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 12,
},
platformInfo: {
backgroundColor: '#ecf0f1',
padding: 12,
borderRadius: 6,
marginBottom: 16,
},
infoLabel: {
fontSize: 14,
color: '#2c3e50',
marginBottom: 4,
},
button: {
paddingVertical: 12,
paddingHorizontal: 20,
borderRadius: 6,
alignItems: 'center',
marginVertical: 4,
},
primaryButton: {
backgroundColor: '#3498db',
},
secondaryButton: {
backgroundColor: '#95a5a6',
},
dangerButton: {
backgroundColor: '#e74c3c',
},
shareButton: {
backgroundColor: '#27ae60',
marginLeft: 8,
flex: 1,
},
buttonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
platformSpecificUI: {
marginTop: 16,
},
iosUI: {
backgroundColor: '#f8f9fa',
padding: 16,
borderRadius: 8,
borderWidth: 1,
borderColor: '#ddd',
},
iosLabel: {
fontSize: 16,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 12,
textAlign: 'center',
},
iosButton: {
backgroundColor: '#007AFF',
padding: 12,
borderRadius: 8,
alignItems: 'center',
},
iosButtonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
androidUI: {
backgroundColor: '#f8f9fa',
padding: 16,
borderRadius: 8,
borderWidth: 1,
borderColor: '#ddd',
},
androidLabel: {
fontSize: 16,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 12,
textAlign: 'center',
},
androidButton: {
backgroundColor: '#4CAF50',
padding: 12,
borderRadius: 4,
alignItems: 'center',
elevation: 2,
},
androidButtonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
locationInfo: {
backgroundColor: '#ecf0f1',
padding: 12,
borderRadius: 6,
marginBottom: 12,
},
shareContainer: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 12,
},
shareInput: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 6,
padding: 12,
fontSize: 16,
marginRight: 8,
},
placeholderText: {
fontSize: 14,
color: '#7f8c8d',
fontStyle: 'italic',
textAlign: 'center',
marginVertical: 8,
},
statusContainer: {
alignItems: 'center',
marginBottom: 16,
},
statusText: {
fontSize: 16,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 12,
},
permissionsStatus: {
backgroundColor: '#f8f9fa',
padding: 12,
borderRadius: 6,
},
deviceInfo: {
backgroundColor: '#ecf0f1',
padding: 12,
borderRadius: 6,
},
nativeModuleInfo: {
backgroundColor: '#fff3cd',
border: 1,
borderColor: '#ffeaa7',
borderRadius: 6,
padding: 12,
marginTop: 16,
},
eventLog: {
maxHeight: 200,
backgroundColor: '#f8f9fa',
borderRadius: 6,
},
eventItem: {
backgroundColor: '#fff',
padding: 12,
marginBottom: 4,
borderRadius: 4,
borderLeftWidth: 3,
borderLeftColor: '#3498db',
},
eventName: {
fontSize: 14,
fontWeight: '600',
color: '#2c3e50',
marginBottom: 2,
},
eventData: {
fontSize: 12,
color: '#7f8c8d',
marginBottom: 2,
},
eventTime: {
fontSize: 10,
color: '#95a5a6',
},
});
export default NativeIntegrationApp;