تطبيق عملي: Stack و Tabs في تطبيق واحد — أساسيات React Native
React Navigation
التثبيت
npm install @react-navigation/native
npm install @react-navigation/native-stack
npm install @react-navigation/bottom-tabs
npx expo install react-native-screens react-native-safe-area-contextأنواع Navigation
1. Stack Navigator
- شاشات فوق بعض (مثل الصفحات)
- زر رجوع تلقائي
2. Tab Navigator
- قائمة سفلية
- تبديل بين الشاشات
3. Drawer Navigator
- قائمة جانبية
- تُفتح بالسحب
المفاهيم الأساسية
navigation prop
- navigate(): الانتقال لشاشة
- goBack(): الرجوع
- push(): إضافة للـ stack
- setParams(): تعديل المعاملات
route prop
- params: المعاملات المُمرّرة
- name: اسم الشاشة الحالية
تمرير البيانات بين الشاشات
// الإرسال
navigation.navigate('Details', { itemId: 42, title: 'منتج' });
// الاستقبال
const { itemId, title } = route.params;// تطبيق كامل مع Navigation
import React from 'react';
import { View, Text, Button, FlatList, StyleSheet, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
// ===== 1. Stack Navigator - المنتجات =====
const Stack = createNativeStackNavigator();
const products = [
{ id: '1', name: 'هاتف iPhone', price: 999 },
{ id: '2', name: 'لابتوب MacBook', price: 1999 },
{ id: '3', name: 'سماعات AirPods', price: 199 },
];
function ProductList({ navigation }) {
return (
<View style={styles.container}>
<FlatList
data={products}
keyExtractor={item => item.id}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.productCard}
onPress={() => navigation.navigate('ProductDetails', { product: item })}
>
<Text style={styles.productName}>{item.name}</Text>
<Text style={styles.productPrice}>${item.price}</Text>
</TouchableOpacity>
)}
/>
</View>
);
}
function ProductDetails({ route, navigation }) {
const { product } = route.params;
return (
<View style={styles.container}>
<Text style={styles.title}>{product.name}</Text>
<Text style={styles.price}>السعر: ${product.price}</Text>
<Button
title="إضافة للسلة 🛒"
onPress={() => navigation.navigate('Cart', { product })}
/>
</View>
);
}
function CartScreen({ route }) {
const product = route.params?.product;
return (
<View style={styles.container}>
<Text style={styles.title}>🛒 السلة</Text>
{product ? (
<View style={styles.cartItem}>
<Text>{product.name}</Text>
<Text>${product.price}</Text>
</View>
) : (
<Text>السلة فارغة</Text>
)}
</View>
);
}
function ProductsStack() {
return (
<Stack.Navigator
screenOptions={{
headerStyle: { backgroundColor: '#6200ee' },
headerTintColor: '#fff',
headerTitleStyle: { fontWeight: 'bold' },
}}
>
<Stack.Screen
name="ProductList"
component={ProductList}
options={{ title: '🛍️ المنتجات' }}
/>
<Stack.Screen
name="ProductDetails"
component={ProductDetails}
options={({ route }) => ({ title: route.params.product.name })}
/>
<Stack.Screen
name="Cart"
component={CartScreen}
options={{ title: 'السلة' }}
/>
</Stack.Navigator>
);
}
// ===== 2. Tab Navigator - التطبيق الرئيسي =====
const Tab = createBottomTabNavigator();
function HomeScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>🏠 الرئيسية</Text>
<Text>مرحباً بك في التطبيق!</Text>
</View>
);
}
function ProfileScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>👤 الملف الشخصي</Text>
</View>
);
}
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused ? 'home' : 'home-outline';
} else if (route.name === 'Shop') {
iconName = focused ? 'cart' : 'cart-outline';
} else if (route.name === 'Profile') {
iconName = focused ? 'person' : 'person-outline';
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#6200ee',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} options={{ title: 'الرئيسية' }} />
<Tab.Screen name="Shop" component={ProductsStack} options={{ headerShown: false, title: 'المتجر' }} />
<Tab.Screen name="Profile" component={ProfileScreen} options={{ title: 'حسابي' }} />
</Tab.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 16 },
title: { fontSize: 24, fontWeight: 'bold', marginBottom: 16 },
productCard: {
padding: 16,
backgroundColor: '#f5f5f5',
borderRadius: 8,
marginBottom: 8,
},
productName: { fontSize: 18, fontWeight: '600' },
productPrice: { fontSize: 16, color: '#6200ee', marginTop: 4 },
price: { fontSize: 20, marginVertical: 16 },
cartItem: {
padding: 16,
backgroundColor: '#e8f5e9',
borderRadius: 8,
marginTop: 16,
},
});اختبر فهمك