Kodax

تطبيق عملي: 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,
  },
});
اختبر فهمك