الواجهة BackHandler في React Native

من موسوعة حسوب

اكتشاف الضغطات على زر الجهاز الخاص بالتنقل للوراء (back navigation)، إذ تسمح لك هذه الواجهة بتسجيل مستمع لحدث لأفعال زر الرجوع للوراء الخاصة بالمنصة، وبذلك يمكن لتطبيق التحكم بكيفية الاستجابة لذلك الزر.

تُستدعى اشتراكات الحدث (event subscriptions) بترتيب عكسي (أي أنّ الأولويّة لآخر اشتراك مسجل) وإذا أعاد اشتراك واحد القيمةَ ‎‎true‎‎، فلن تُستدعى الاشتراكات المسجلة السابقة. إن لم يعد أي إشتراك القيمة true أو لم يكن أيًا منها مسجلًا، فسيُستدعى الإجراء الافتراضي لزر الرجوع وذلك للخروج من التطبيق.

تحذير: إذا أظهر تطبيقك نافذة شرطيّة (‎‎Modal‎‎) مفتوحة، فلن تنشر واجهة BackHandler أي أحداث (انظر توثيق المكون Modal‎‎).

مثال

إليك مثال عن نمط الاستخدام:

BackHandler.addEventListener('hardwareBackPress', function() {
  //  this.onMainScreen و this.goBack
  // مثالان فقط، ستحتاج إلى استخدام توابعك الخاصة هنا
  // عادةً ما يُستخدم مكوّن الانتقال هنا للرجوع إلى الحالة السابقة

  if (!this.onMainScreen()) {
    this.goBack();
    return true;
  }
  return false;
});

أما المثال التالي فهو يمثل حالة يؤكد فيها التطبيق على خروج المستخدم منه:

import React, { useEffect } from "react";
import { Text, View, StyleSheet, BackHandler, Alert } from "react-native";

const App = () => {
  useEffect(() => {
    const backAction = () => {
      Alert.alert("Hold on!", "Are you sure you want to go back?", [
        {
          text: "Cancel",
          onPress: () => null,
          style: "cancel"
        },
        { text: "YES", onPress: () => BackHandler.exitApp() }
      ]);
      return true;
    };

    const backHandler = BackHandler.addEventListener(
      "hardwareBackPress",
      backAction
    );

    return () => backHandler.remove();
  }, []);

  return (
    <View style={styles.container}>
      <Text style={styles.text}>Click Back button!</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  text: {
    fontSize: 18,
    fontWeight: "bold"
  }
});

export default App;
import React, { Component } from "react";
import { Text, View, StyleSheet, BackHandler, Alert } from "react-native";

class App extends Component {
  backAction = () => {
    Alert.alert("Hold on!", "Are you sure you want to go back?", [
      {
        text: "Cancel",
        onPress: () => null,
        style: "cancel"
      },
      { text: "YES", onPress: () => BackHandler.exitApp() }
    ]);
    return true;
  };

  componentDidMount() {
    this.backHandler = BackHandler.addEventListener(
      "hardwareBackPress",
      this.backAction
    );
  }

  componentWillUnmount() {
    this.backHandler.remove();
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>Click Back button!</Text>
      </View>
    );
  }
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  text: {
    fontSize: 18,
    fontWeight: "bold"
  }
});

export default App;

ينشئ BackHandler.addEventListener مستمع حدث ويعيد كائنًا من النوع NativeEventSubscription والذي يجيب أن يُزال باستعمال التابع NativeEventSubscription.remove، أضف إلى ذلك أن التابع BackHandler.removeEventListener يمكن أن يستخدم للغرض نفسه أيضًا، واحرص على أن دالة رد النداء تملك المرجع نفسه الذي استعمل عند استدعاء addEventListener كما موضح في المثال التالي:

import React, { useEffect } from "react";
import { Text, View, StyleSheet, BackHandler, Alert } from "react-native";

const App = () => {
  const backAction = () => {
    Alert.alert("Hold on!", "Are you sure you want to go back?", [
      {
        text: "Cancel",
        onPress: () => null,
        style: "cancel"
      },
      { text: "YES", onPress: () => BackHandler.exitApp() }
    ]);
    return true;
  };

  useEffect(() => {
    BackHandler.addEventListener("hardwareBackPress", backAction);

    return () =>
      BackHandler.removeEventListener("hardwareBackPress", backAction);
  }, []);

  return (
    <View style={styles.container}>
      <Text style={styles.text}>Click Back button!</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  text: {
    fontSize: 18,
    fontWeight: "bold"
  }
});

export default App;
import React, { Component } from "react";
import { Text, View, StyleSheet, BackHandler, Alert } from "react-native";

class App extends Component {
  backAction = () => {
    Alert.alert("Hold on!", "Are you sure you want to go back?", [
      {
        text: "Cancel",
        onPress: () => null,
        style: "cancel"
      },
      { text: "YES", onPress: () => BackHandler.exitApp() }
    ]);
    return true;
  };

  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.backAction);
  }

  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress", this.backAction);
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>Click Back button!</Text>
      </View>
    );
  }
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  text: {
    fontSize: 18,
    fontWeight: "bold"
  }
});

export default App;

الاستعمال مع متنقل React

إن كنت تستعمل متنقل React أي React Navigation للتنقل بين مختلف الشاشات، فيمكنك أن تتبع دليلهم هذا.

استعمال خطاف Backhandler

لدى خطافات React Native خطافًا جيدًا هو useBackHandler والذي يسهل كثيرًا عملية ضبط مستمعات الأحداث.

التوابع

‎‎addEventListener()‎‎

static addEventListener(eventName, handler)

‎‎exitApp()‎‎

static exitApp()

‎‎removeEventListener()‎‎

static removeEventListener(eventName, handler)

مصادر