التنقل بين الشاشات في React Native
نادرًا ما تتكون تطبيقات الجوال من شاشة واحدة فقط. عادةً ما يُدار عرض شاشاتٍ متعدّدة والتحويل بينها بما يعرف بالمتنقّل (navigator).
يغطي هذا الدليل مكونات التنقّل المتوفرة في React Native. إذا كان مفهوم التنقّل جديدًا عليك، فربما من الأفضل أن تستخدم مكتبة React Navigation التي توفّر حلًّا سهل الاستخدام لإدارة التنقّل بين الشاشات، مع القدرة على استخدام نمطي التنقل المُكدَّس (stack navigation) والتنقل المبوب (tabbed navigation) الشائعين على كل من نظامي التشغيل iOS وAndroid.
إذا كنت تستهدف نظام التشغيل iOS فقط، فانظر NavigatorIOS
لطريقةٍ توفِّر مظهرًا أصيلًا سهلَ الإعداد، إذ يُوفّر غلافًا (wrapper) حول الصّنف الأصيل UINavigationController
. لكنّ هذا المكون لن يعمل على Android.
إذا أردت مظهرًا أصيلًا على كل من نظامي التشغيل iOS وAndroid، أو إذا كنت بصدد دمج React Native مع تطبيق أصيل يعمل بالفعل على إدارة التنقّل، فمكتبة react-native-navigation توفر تنقّلًا أصيلًا على كلا النظامين.
الحل الذي يتبنّاه مجتمع المطورين هو مكتبةٌ قائمة بذاتها تسمح للمطورين بإعداد شاشات التطبيق باستخدام بضعة أسطر من الشيفرة.
الخطوة الأولى هي تثبيتها في مشروعك:
npm install --save react-navigation
يمكنك بعد ذلك إنشاء تطبيقٍ بسرعة باستخدام شاشة رئيسية وشاشة ملف شخصي كالتالي:
import {createStackNavigator, createAppNavigator} from 'react-navigation';
const MainNavigator = createStackNavigator({
Home: {screen: HomeScreen},
Profile: {screen: ProfileScreen},
});
const App = createAppNavigator(MainNavigator);
export default App;
يمكن لكل مكوّن شاشةٍ تعيين خيارات التنقل مثل عنوان الترويسة (header). يمكن للمكتبة استخدام منشئي تأثيرات (action creators) على خاصيّة navigation
لإنشاء روابط توصِل إلى شاشاتٍ أخرى (انظر الدالةَ navigate()
التي استُخرِجَت من this.props.navigation
أسفله):
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const {navigate} = this.props.navigation;
return (
<Button
title="Go to Jane's profile"
onPress={() => navigate('Profile', {name: 'Jane'})}
/>
);
}
}
تُسهِّل موجّهات (routers) مكتبةِ React Navigation الهيمنة على (override) آليّة عمل التنقل. ولأنّ الموجّهات قابلة للتّداخل (nested) داخل بعضها البعض، فيمكن للمطورين تغيير منطق التنقل في منطقة واحدة من التطبيق دون إجراء تغييرات واسعة النطاق.
تستخدم عروضُ React Navigation مكوّناتٍ أصيلة مع مكتبة التحريك Animated
لتقديم تحريكاتِ 60 إطارًا في الثانية (60fps) تُشغَّل على السلسلة الأصيلة (native thread). إضافةً إلى إمكانيّة تخصيص التحريكات والإيماءات بسهولة.
لمقدمة كاملة حول React Navigation، اتبع دليل React Navigation، أو تصفح توثيقات أخرى كهذه الصفحة.
يبدو المكوّن NavigatorIOS
مطابقًا للصنف UINavigationController
، وهذا لأنه مبنيّ عليه.
مثال:
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
passProps: {myProp: 'foo'},
}}
/>
يستخدم NavigatorIOS
الموجّهات (routes) لتمثيل الشاشات بشكل مشابهٍ لأنظمة التنقل الأخرى، مع بعض الاختلافات المهمة. يمكن تحديد المكون الفعلي الذي سيُصيَّر بمفتاح component
في الموجّه، ويمكن تحديد أي خاصيّاتٍ لتُمرَّر إلى هذا المكون داخل passProps
. سيُمرَّرُ كائنُ navigator
تلقائيًا كخاصيّةٍ للمكوّن، ما يسمح لك باستدعاء كل من push
وpop
حسب الحاجة.
لأنّ المكوّن NavigatorIOS
يعتمد على آليات التّنقل التي توفِّرها أدوات UIKit الأصيلة، فسيعرض تلقائيًا شريط تنقّلٍ مع عنوانٍ وزر رجوع.
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 {
static propTypes = {
route: PropTypes.shape({
title: PropTypes.string.isRequired,
}),
navigator: PropTypes.object.isRequired,
};
constructor(props, context) {
super(props, context);
this._onForward = this._onForward.bind(this);
}
_onForward() {
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>
);
}
}
انظر توثيق NavigatorIOS
للمزيد من المعلومات حول هذا المكون.