الفرق بين المراجعتين ل"ReactNative/navigation"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 1: سطر 1:
 
<noinclude>{{DISPLAYTITLE:التنقل بين الشاشات في React Native}}</noinclude>
 
<noinclude>{{DISPLAYTITLE:التنقل بين الشاشات في React Native}}</noinclude>
نادرًا ما تتكون تطبيقات الجوال من شاشة واحدة فقط. عادةً ما يُدار عرض شاشاتٍ متعدّدة والتحويل بينها بما يعرف بالمتنقّل (navigator).
+
تتكون تطبيقات الجوّال نادرًا من شاشة واحدة فقط، حيث يدير ما يُعرَف بالمتنقّل navigator عرض شاشاتٍ متعدّدة ويحوّل بينها.
  
يغطي هذا الدليل مكونات التنقّل المتوفرة في React Native. إذا كان مفهوم التنقّل جديدًا عليك، فربما  من الأفضل أن تستخدم مكتبة [https://facebook.github.io/react-native/docs/navigation#react-navigation React Navigation] التي توفّر حلًّا سهل الاستخدام لإدارة التنقّل بين الشاشات، مع القدرة على استخدام نمطي التنقل المُكدَّس (stack navigation) والتنقل المبوب (tabbed navigation) الشائعين على كل من نظامي التشغيل iOS وAndroid.
+
يغطّي هذا الدليل مكونات التنقّل المتوفرة في React Native. إذا كان مفهوم التنقّل جديدًا عليك، فيُفضَّل أن تستخدم مكتبة React Navigation التي توفّر حلًّا سهل الاستخدام للتنقّل بين الشاشات، مع القدرة على استخدام نمطَي التنقل المُكدَّس stack navigation والتنقل المبوَّب tabbed navigation الشائعين على كل من نظامي التشغيل iOS و Android.
  
إذا كنت تستهدف نظام التشغيل iOS فقط، فانظر <code>[[ReactNative/navigatorios|NavigatorIOS]]</code> لطريقةٍ توفِّر مظهرًا أصيلًا سهلَ الإعداد، إذ يُوفّر غلافًا (wrapper) حول الصّنف الأصيل ‎<code>UINavigationController</code>‎. لكنّ هذا المكون لن يعمل على Android.
+
إذا أردت مظهرًا وإحساسًا أصيلًا على كل من نظامي التشغيل iOS و Android، أو إذا كنت بصدد دمج React Native مع تطبيق أصيل يدير التنقّل بالفعل، فمكتبة [https://github.com/wix/react-native-navigation react-native-navigation] توفر تنقّلًا أصيلًا على كلِّ من النظامين.
  
إذا أردت مظهرًا أصيلًا على كل من نظامي التشغيل iOS وAndroid، أو إذا كنت بصدد دمج React Native مع تطبيق أصيل يعمل بالفعل على إدارة التنقّل، فمكتبة [https://github.com/wix/react-native-navigation react-native-navigation] توفر تنقّلًا أصيلًا على كلا النظامين.
+
==مكتبة React Navigation==
 
 
==React Navigation==
 
 
الحل الذي يتبنّاه مجتمع المطورين هو مكتبةٌ قائمة بذاتها تسمح للمطورين بإعداد شاشات التطبيق باستخدام بضعة أسطر من الشيفرة.
 
الحل الذي يتبنّاه مجتمع المطورين هو مكتبةٌ قائمة بذاتها تسمح للمطورين بإعداد شاشات التطبيق باستخدام بضعة أسطر من الشيفرة.
  
الخطوة الأولى هي تثبيتها في مشروعك:
+
=== التثبيت والإعداد ===
<syntaxhighlight lang="javascript">
+
يجب أولًا تثبيت هذه المكتبة في مشروعك:
npm install --save react-navigation
+
<syntaxhighlight lang="bash">
 +
npm install @react-navigation/native @react-navigation/stack
 
</syntaxhighlight>
 
</syntaxhighlight>
يمكنك بعد ذلك إنشاء تطبيقٍ بسرعة باستخدام شاشة رئيسية وشاشة ملف شخصي كالتالي:
+
ثم ثبّت اعتماديات الأنداد المطلوبة. تحتاج إلى تشغيل أوامر مختلفة اعتمادًا على ما إذا كان مشروعك عبارة عن مشروع يديره Expo أو مشروع React Native صِرف.
<syntaxhighlight lang="javascript">
+
 
import {createStackNavigator, createAppNavigator} from 'react-navigation';
+
إذا كان لديك مشروع يديره Expo، فثبّت الاعتماديات باستخدام الأمر <code>expo</code>:<syntaxhighlight lang="bash">
 +
expo install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
 +
</syntaxhighlight>إذا كان لديك مشروع React Native صِرف، فثبّت الاعتماديات باستخدام الأمر <code>npm</code>:<syntaxhighlight lang="bash">
 +
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
 +
</syntaxhighlight>تأكّد من تثبيت [https://cocoapods.org/ Cocoapods] بالنسبة لنظام iOS مع مشروع React Native الصِرف،  ثم ثبّت ملفات pod لإكمال التثبيت:<syntaxhighlight lang="bash">
 +
cd ios
 +
pod install
 +
cd ..
 +
</syntaxhighlight>'''ملاحظة''': قد تتلقّى تحذيرات تتعلّق باعتماديات الأنداد بعد التثبيت، التي تكون عادةً ناتجة عن نطاقات إصدارات غير صحيحة محدَّدة في بعض الحزم. يمكنك تجاهل معظم التحذيرات بأمان طالما أنك يُبنى تطبيقك.
  
const MainNavigator = createStackNavigator({
+
أضِف السطر التالي في الجزء العلوي (تأكد من أنه في الجزء العلوي ولا يوجد شيء آخر قبله) من ملف الإدخال مثل الملف <code>index.js</code> أو <code>App.js</code> لإنهاء تثبيت معالج الإيماءات <code>react-native-gesture-handler</code>:<syntaxhighlight lang="javascript">
  Home: {screen: HomeScreen},
+
import 'react-native-gesture-handler';
  Profile: {screen: ProfileScreen},
+
</syntaxhighlight>يجب الآن تغليف التطبيق بأكمله في <code>NavigationContainer</code>،  حيث تطبّق ذلك في ملف الإدخال الخاص بك مثل الملف <code>index.js</code> أو <code>App.js</code>:<syntaxhighlight lang="javascript">
});
+
import 'react-native-gesture-handler';
 +
import * as React from 'react';
 +
import { NavigationContainer } from '@react-navigation/native';
  
const App = createAppNavigator(MainNavigator);
+
const App = () => {
 +
  return (
 +
    <NavigationContainer>
 +
      {/* بقية شيفرة تطبيقك */}
 +
    </NavigationContainer>
 +
  );
 +
};
  
 
export default App;
 
export default App;
</syntaxhighlight>
+
</syntaxhighlight>يمكنك الآن بناء وتشغيل تطبيقك على محاكٍ أو على جهاز فعلي.
يمكن لكل مكوّن شاشةٍ تعيين خيارات التنقل مثل عنوان الترويسة (header). يمكن للمكتبة استخدام منشئي تأثيرات (action creators) على خاصيّة ‎<code>navigation</code>‎ لإنشاء روابط توصِل إلى شاشاتٍ أخرى (انظر الدالةَ ‎<code>navigate()‎</code>‎ التي استُخرِجَت من ‎<code>this.props.navigation</code>‎ أسفله):
+
 
 +
=== الاستخدام ===
 +
يمكنك بعد ذلك إنشاء تطبيقٍ يتألف من شاشة رئيسية home وشاشة ملف تعريفي profile كالتالي:
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
class HomeScreen extends React.Component {
+
import * as React from 'react';
  static navigationOptions = {
+
import { NavigationContainer } from '@react-navigation/native';
    title: 'Welcome',
+
import { createStackNavigator } from '@react-navigation/stack';
  };
 
  render() {
 
    const {navigate} = this.props.navigation;
 
    return (
 
      <Button
 
        title="Go to Jane's profile"
 
        onPress={() => navigate('Profile', {name: 'Jane'})}
 
      />
 
    );
 
  }
 
}
 
</syntaxhighlight>
 
تُسهِّل موجّهات (routers) مكتبةِ [https://facebook.github.io/react-native/docs/navigation#react-navigation React Navigation] الهيمنة على (override) آليّة عمل التنقل. ولأنّ الموجّهات قابلة للتّداخل (nested) داخل بعضها البعض، فيمكن للمطورين تغيير منطق التنقل في منطقة واحدة من التطبيق دون إجراء تغييرات واسعة النطاق.
 
  
تستخدم عروضُ React Navigation مكوّناتٍ أصيلة مع مكتبة التحريك [[ReactNative/animated|‎<code>Animated</code>‎]] لتقديم تحريكاتِ 60 إطارًا في الثانية (60fps) تُشغَّل على السلسلة الأصيلة (native thread). إضافةً إلى إمكانيّة تخصيص التحريكات والإيماءات بسهولة.
+
const Stack = createStackNavigator();
  
لمقدمة كاملة حول React Navigation، اتبع [https://reactnavigation.org/docs/getting-started.html دليل React Navigation]، أو تصفح توثيقات أخرى [https://expo.io/@react-navigation/NavigationPlayground كهذه الصفحة].
+
const MyStack = () => {
 
+
  return (
==المكوّن ‎<code>NavigatorIOS</code>‎==
+
    <NavigationContainer>
يبدو المكوّن ‎<code>NavigatorIOS</code>‎ مطابقًا للصنف [https://developer.apple.com/documentation/uikit/uinavigationcontroller ‎<code>UINavigationController</code>‎]، وهذا لأنه مبنيّ عليه.
+
      <Stack.Navigator>
[[ملف:NavigationStack-NavigatorIOS.gif|مركز|لاإطار]]مثال:<syntaxhighlight lang="javascript">
+
        <Stack.Screen
<NavigatorIOS
+
          name="Home"
  initialRoute={{
+
          component={HomeScreen}
    component: MyScene,
+
          options={{ title: 'Welcome' }}
    title: 'My Initial Scene',
+
        />
    passProps: {myProp: 'foo'},
+
        <Stack.Screen name="Profile" component={ProfileScreen} />
  }}
+
      </Stack.Navigator>
/>
+
    </NavigationContainer>
 +
  );
 +
};
 
</syntaxhighlight>
 
</syntaxhighlight>
يستخدم ‎<code>NavigatorIOS</code>‎ الموجّهات (routes) لتمثيل الشاشات بشكل مشابهٍ لأنظمة التنقل الأخرى، مع بعض الاختلافات المهمة. يمكن تحديد المكون الفعلي الذي سيُصيَّر بمفتاح ‎<code>component</code>‎ في الموجّه، ويمكن تحديد أي خاصيّاتٍ لتُمرَّر إلى هذا المكون داخل ‎<code>passProps</code>‎. سيُمرَّرُ كائنُ ‎<code>navigator</code>‎ تلقائيًا كخاصيّةٍ للمكوّن، ما يسمح لك باستدعاء كل من ‎<code>push</code>‎ و‎<code>pop</code>‎ حسب الحاجة.
+
هناك شاشتان في هذا المثال (الصفحة الرئيسية <code>Home</code> والملف التعريفي <code>Profile</code>) جرى تعريفهما باستخدام المكوّن <code>Stack.Screen</code>، وهكذا يمكنك تعريف أي عدد تريده من الشاشات.
 
 
لأنّ المكوّن ‎<code>NavigatorIOS</code>‎ يعتمد على آليات التّنقل التي توفِّرها أدوات UIKit الأصيلة، فسيعرض تلقائيًا شريط تنقّلٍ مع عنوانٍ وزر رجوع.
 
<syntaxhighlight lang="javascript">
 
import React from 'react';
 
import PropTypes from 'prop-types';
 
import {Button, NavigatorIOS, Text, View} from 'react-native';
 
  
export default class NavigatorIOSApp extends React.Component {
+
يمكنك ضبط خيارات مثل عنوان كل شاشة في الخاصية <code>options</code> التابعة للمكوّن <code>Stack.Screen</code>.
  render() {
 
    return (
 
      <NavigatorIOS
 
        initialRoute={{
 
          component: MyScene,
 
          title: 'My Initial Scene',
 
          passProps: {index: 1},
 
        }}
 
        style={{flex: 1}}
 
      />
 
    );
 
  }
 
}
 
  
class MyScene extends React.Component {
+
تأخذ كل شاشة خاصية مكوّن <code>component</code> والتي هي أيضًا من مكونات React. تتلقّى هذه المكونات خاصية تسمى التنقل <code>navigation</code> التي لها توابع مختلفة للربط بشاشات أخرى، حيث يمكنك استخدام التابع <code>navigation.navigate</code> مثلًا للذهاب إلى الشاشة <code>Profile</code>:<syntaxhighlight lang="javascript">
   static propTypes = {
+
const HomeScreen = ({ navigation }) => {
    route: PropTypes.shape({
+
   return (
       title: PropTypes.string.isRequired,
+
    <Button
     }),
+
      title="Go to Jane's profile"
    navigator: PropTypes.object.isRequired,
+
      onPress={() =>
  };
+
        navigation.navigate('Profile', { name: 'Jane' })
 +
       }
 +
     />
 +
  );
 +
};
 +
const ProfileScreen = ({ navigation, route }) => {
 +
  return <Text>This is {route.params.name}'s profile</Text>;
 +
};
 +
</syntaxhighlight>تستخدم العروضُ views في المتنقّل المُكدَّس stack navigator المكونات الأصيلة مع مكتبة التحريك [[ReactNative/animated|‎<code>Animated</code>‎]] لتقديم تحريكاتٍ بمعدّل 60 إطارًا في الثانية (60fps) تُشغَّل على الخيط الأصيل native thread، بالإضافة إلى إمكانيّة تخصيص التحريكات والإيماءات.
  
  constructor(props, context) {
+
تحتوي المكتبة React Navigation أيضًا على حزم لأنواع مختلفة من المتنقّلات navigators مثل التبويبات tabs والسحب drawer، التي يمكنك استخدامها لتطبيق أنماط مختلفة في تطبيقك.
    super(props, context);
 
    this._onForward = this._onForward.bind(this);
 
  }
 
  
  _onForward() {
+
اتبع [https://reactnavigation.org/docs/getting-started/ دليل بدء استخدام React Navigation]، للاطّلاع على مقدمة كاملة عنها.
    let nextIndex = ++this.props.index;
 
    this.props.navigator.push({
 
      component: MyScene,
 
      title: 'Scene ' + nextIndex,
 
      passProps: {index: nextIndex},
 
    });
 
  }
 
 
 
  render() {
 
    return (
 
      <View>
 
        <Text>Current Scene: {this.props.title}</Text>
 
        <Button
 
          onPress={this._onForward}
 
          title="Tap me to load the next scene"
 
        />
 
      </View>
 
    );
 
  }
 
}
 
</syntaxhighlight>
 
  
انظر توثيق [[ReactNative/navigatorios|‎<code>NavigatorIOS</code>‎]]  للمزيد من المعلومات حول هذا المكون.
 
 
== مصادر ==
 
== مصادر ==
* [https://facebook.github.io/react-native/docs/navigation صفحة Navigating Between Screens في توثيق React Native الرسمي.]
+
* [https://reactnative.dev/docs/navigation صفحة Navigating Between Screens في توثيق React Native الرسمي.]
 
[[تصنيف:ReactNative]]
 
[[تصنيف:ReactNative]]

مراجعة 15:55، 2 يوليو 2021

تتكون تطبيقات الجوّال نادرًا من شاشة واحدة فقط، حيث يدير ما يُعرَف بالمتنقّل navigator عرض شاشاتٍ متعدّدة ويحوّل بينها.

يغطّي هذا الدليل مكونات التنقّل المتوفرة في React Native. إذا كان مفهوم التنقّل جديدًا عليك، فيُفضَّل أن تستخدم مكتبة React Navigation التي توفّر حلًّا سهل الاستخدام للتنقّل بين الشاشات، مع القدرة على استخدام نمطَي التنقل المُكدَّس stack navigation والتنقل المبوَّب tabbed navigation الشائعين على كل من نظامي التشغيل iOS و Android.

إذا أردت مظهرًا وإحساسًا أصيلًا على كل من نظامي التشغيل iOS و Android، أو إذا كنت بصدد دمج React Native مع تطبيق أصيل يدير التنقّل بالفعل، فمكتبة react-native-navigation توفر تنقّلًا أصيلًا على كلِّ من النظامين.

مكتبة React Navigation

الحل الذي يتبنّاه مجتمع المطورين هو مكتبةٌ قائمة بذاتها تسمح للمطورين بإعداد شاشات التطبيق باستخدام بضعة أسطر من الشيفرة.

التثبيت والإعداد

يجب أولًا تثبيت هذه المكتبة في مشروعك:

npm install @react-navigation/native @react-navigation/stack

ثم ثبّت اعتماديات الأنداد المطلوبة. تحتاج إلى تشغيل أوامر مختلفة اعتمادًا على ما إذا كان مشروعك عبارة عن مشروع يديره Expo أو مشروع React Native صِرف.

إذا كان لديك مشروع يديره Expo، فثبّت الاعتماديات باستخدام الأمر expo:

expo install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

إذا كان لديك مشروع React Native صِرف، فثبّت الاعتماديات باستخدام الأمر npm:

npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

تأكّد من تثبيت Cocoapods بالنسبة لنظام iOS مع مشروع React Native الصِرف، ثم ثبّت ملفات pod لإكمال التثبيت:

cd ios
pod install
cd ..

ملاحظة: قد تتلقّى تحذيرات تتعلّق باعتماديات الأنداد بعد التثبيت، التي تكون عادةً ناتجة عن نطاقات إصدارات غير صحيحة محدَّدة في بعض الحزم. يمكنك تجاهل معظم التحذيرات بأمان طالما أنك يُبنى تطبيقك. أضِف السطر التالي في الجزء العلوي (تأكد من أنه في الجزء العلوي ولا يوجد شيء آخر قبله) من ملف الإدخال مثل الملف index.js أو App.js لإنهاء تثبيت معالج الإيماءات react-native-gesture-handler:

import 'react-native-gesture-handler';

يجب الآن تغليف التطبيق بأكمله في NavigationContainer، حيث تطبّق ذلك في ملف الإدخال الخاص بك مثل الملف index.js أو App.js:

import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

const App = () => {
  return (
    <NavigationContainer>
      {/* بقية شيفرة تطبيقك */}
    </NavigationContainer>
  );
};

export default App;

يمكنك الآن بناء وتشغيل تطبيقك على محاكٍ أو على جهاز فعلي.

الاستخدام

يمكنك بعد ذلك إنشاء تطبيقٍ يتألف من شاشة رئيسية home وشاشة ملف تعريفي profile كالتالي:

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

const MyStack = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{ title: 'Welcome' }}
        />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

هناك شاشتان في هذا المثال (الصفحة الرئيسية Home والملف التعريفي Profile) جرى تعريفهما باستخدام المكوّن Stack.Screen، وهكذا يمكنك تعريف أي عدد تريده من الشاشات.

يمكنك ضبط خيارات مثل عنوان كل شاشة في الخاصية options التابعة للمكوّن Stack.Screen.

تأخذ كل شاشة خاصية مكوّن component والتي هي أيضًا من مكونات React. تتلقّى هذه المكونات خاصية تسمى التنقل navigation التي لها توابع مختلفة للربط بشاشات أخرى، حيث يمكنك استخدام التابع navigation.navigate مثلًا للذهاب إلى الشاشة Profile:

const HomeScreen = ({ navigation }) => {
  return (
    <Button
      title="Go to Jane's profile"
      onPress={() =>
        navigation.navigate('Profile', { name: 'Jane' })
      }
    />
  );
};
const ProfileScreen = ({ navigation, route }) => {
  return <Text>This is {route.params.name}'s profile</Text>;
};

تستخدم العروضُ views في المتنقّل المُكدَّس stack navigator المكونات الأصيلة مع مكتبة التحريك Animated لتقديم تحريكاتٍ بمعدّل 60 إطارًا في الثانية (60fps) تُشغَّل على الخيط الأصيل native thread، بالإضافة إلى إمكانيّة تخصيص التحريكات والإيماءات.

تحتوي المكتبة React Navigation أيضًا على حزم لأنواع مختلفة من المتنقّلات navigators مثل التبويبات tabs والسحب drawer، التي يمكنك استخدامها لتطبيق أنماط مختلفة في تطبيقك.

اتبع دليل بدء استخدام React Navigation، للاطّلاع على مقدمة كاملة عنها.

مصادر