الفرق بين المراجعتين لصفحة: «ReactNative/navigation»

من موسوعة حسوب
لا ملخص تعديل
طلا ملخص تعديل
 
(3 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة)
سطر 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/native-stack
</syntaxhighlight>
</syntaxhighlight>
يمكنك بعد ذلك إنشاء تطبيقٍ بسرعة باستخدام شاشة رئيسية وشاشة ملف شخصي كالتالي:
ثم ثبّت اعتماديات الأنداد peer dependencies المطلوبة. تحتاج إلى تشغيل أوامر مختلفة اعتمادًا على ما إذا كان مشروعك عبارة عن مشروع يديره Expo أو مشروع React Native صِرف.
<syntaxhighlight lang="javascript">
import {createStackNavigator, createAppNavigator} from 'react-navigation';


const MainNavigator = createStackNavigator({
إذا كان لديك مشروع يديره Expo، فثبّت الاعتماديات باستخدام أمر <code>expo</code> التالي:<syntaxhighlight lang="bash">
  Home: {screen: HomeScreen},
expo install react-native-screens react-native-safe-area-context
  Profile: {screen: ProfileScreen},
</syntaxhighlight>إذا كان لديك مشروع React Native صِرف، فثبّت الاعتماديات باستخدام أمر <code>npm</code> التالي:<syntaxhighlight lang="bash">
});
npm install react-native-screens react-native-safe-area-context
</syntaxhighlight>تأكّد من تثبيت [https://cocoapods.org/ Cocoapods] بالنسبة لنظام iOS مع مشروع React Native الصِرف، ثم ثبّت ملفات pod لإكمال التثبيت:<syntaxhighlight lang="bash">
cd ios
pod install
cd ..
</syntaxhighlight><blockquote>'''ملاحظة''': قد تتلقّى تحذيرات تتعلّق باعتماديات الأنداد بعد التثبيت، التي تكون عادةً ناتجة عن نطاقات إصدارات غير صحيحة محدَّدة في بعض الحزم. يمكنك تجاهل معظم التحذيرات بأمان طالما أن تطبيقك يعمل بنجاح.</blockquote>أضِف السطر التالي في الجزء العلوي (تأكد من أنه في الجزء العلوي ولا يوجد شيء آخر قبله) من ملف الإدخال مثل الملف <code>index.js</code> أو <code>App.js</code> لإنهاء تثبيت معالج الإيماءات <code>react-native-gesture-handler</code>:<syntaxhighlight lang="javascript">
import 'react-native-gesture-handler';
</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 { createNativeStackNavigator } from '@react-navigation/native-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 = createNativeStackNavigator();


لمقدمة كاملة حول 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 {
  render() {
    return (
      <NavigatorIOS
        initialRoute={{
          component: MyScene,
          title: 'My Initial Scene',
          passProps: {index: 1},
        }}
        style={{flex: 1}}
      />
    );
  }
}


class MyScene extends React.Component {
يمكنك ضبط خيارات مثل عنوان كل شاشة في الخاصية <code>options</code> التابعة للمكوّن <code>Stack.Screen</code>.
  static propTypes = {
    route: PropTypes.shape({
      title: PropTypes.string.isRequired,
    }),
    navigator: PropTypes.object.isRequired,
  };


  constructor(props, context) {
تأخذ كل شاشة خاصية مكوّن <code>component</code> وهي أيضًا من مكونات React. تتلقّى هذه المكونات خاصية تسمى التنقل <code>navigation</code> التي لها توابع مختلفة للربط بشاشات أخرى، إذ يمكنك استخدام التابع <code>navigation.navigate</code> مثلًا للذهاب إلى الشاشة <code>Profile</code>:<syntaxhighlight lang="javascript">
     super(props, context);
const HomeScreen = ({ navigation }) => {
    this._onForward = this._onForward.bind(this);
  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>;
};
</syntaxhighlight>يستخدم المُتنقِّل <code>native-stack</code> الواجهة البرمجية الأصيلة <code>UINavigationController</code> على نظام iOS والواجهة البرمجية الأصيلة <code>Fragment</code> على نظام Android لذا سيسلك المنتقل المبني مع <code>createNativeStackNavigator</code> السلوك النفسه ويملك سمات الأداء نفسه الذي يكون لدى تطبيق أصيل مبني باستعمال هاتين الواجهتين.


  _onForward() {
تحتوي المكتبة React Navigation أيضًا على حزم لأنواع مختلفة من المتنقّلات navigators مثل التبويبات tabs والسحب drawer، التي يمكنك استخدامها لتطبيق أنماط مختلفة في تطبيقك.
    let nextIndex = ++this.props.index;
    this.props.navigator.push({
      component: MyScene,
      title: 'Scene ' + nextIndex,
      passProps: {index: nextIndex},
    });
  }


  render() {
اتبع [https://reactnavigation.org/docs/getting-started/ دليل بدء استخدام مكتبة React Navigation] الأجنبي للاطّلاع على مقدمة كاملة عنها.
    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]]
[[تصنيف:React Native Docs]]

المراجعة الحالية بتاريخ 13:43، 9 أكتوبر 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/native-stack

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

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

expo install react-native-screens react-native-safe-area-context

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

npm install react-native-screens react-native-safe-area-context

تأكّد من تثبيت 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 { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

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>;
};

يستخدم المُتنقِّل native-stack الواجهة البرمجية الأصيلة UINavigationController على نظام iOS والواجهة البرمجية الأصيلة Fragment على نظام Android لذا سيسلك المنتقل المبني مع createNativeStackNavigator السلوك النفسه ويملك سمات الأداء نفسه الذي يكون لدى تطبيق أصيل مبني باستعمال هاتين الواجهتين.

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

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

مصادر