الواجهة البرمجية AppState في React Native
تُستخدم الواجهة البرمجيّة AppState
لإخبار المستخدم بوجود التّطبيق في الواجهة الأماميّة (foreground)، أو الخلفية (background)، وإشعاره عند تغيّر ذلك.
تُستخدم AppState
كثيرًا لتحديد نيّة الفعل (intent)، وتحضير ما يتوجّب فعله عند معالجة إشعارات الدّفع (push notifications).
حالات التطبيق
- النّشطة
active
: يعمل التّطبيق في الواجهة الأماميّة. - في الخلفيّة
background
: يعمل التطبيق في الخلفية، وتعني أنّ المستخدم في إحدى الحالات التالية:- على تطبيقٍ آخر.
- على الشّاشة الرئيسيّة (home screen).
- (على منصّة Android) المستخدم على نشاط
activity
آخر (حتى لو أُطلِق من تطبيق المستخدم).
- حالة الخمول
inactive
(على منصّة iOS): تحصل هذه الحالة عند الانتقال بين الواجهة الأماميّة والخلفيّة، وخلال فترة الخمول، مثل: الدّخول في العرض متعدّد المهام (Multitasking)، أو عند حدوث اتصالٍ وارد.
ويمكن الإطّلاع على توثيق شركة Apple لمزيدٍ من المعلومات.
الاستخدام الأساسي
يمكن معرفة الحالة الحاليّة من خلال تفحّص الخاصيّة AppState.currentState
، والتي تُحدَّث دائمًا، وتكون قيمتها null
عند بداية التشغيل ثم تستعيدها AppState
عبر الجسر.
- مثال لمكوِّن دالّة (Function Component)
import React, { useRef, useState, useEffect } from "react";
import { AppState, StyleSheet, Text, View } from "react-native";
const AppStateExample = () => {
const appState = useRef(AppState.currentState);
const [appStateVisible, setAppStateVisible] = useState(appState.current);
useEffect(() => {
AppState.addEventListener("change", _handleAppStateChange);
return () => {
AppState.removeEventListener("change", _handleAppStateChange);
};
}, []);
const _handleAppStateChange = (nextAppState) => {
if (
appState.current.match(/inactive|background/) &&
nextAppState === "active"
) {
console.log("App has come to the foreground!");
}
appState.current = nextAppState;
setAppStateVisible(appState.current);
console.log("AppState", appState.current);
};
return (
<View style={styles.container}>
<Text>Current state is: {appStateVisible}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
});
export default AppStateExample;
- مثال لمكوِّن صنف (Class Component)
import React, { Component } from "react";
import { AppState, StyleSheet, Text, View } from "react-native";
class AppStateExample extends Component {
state = {
appState: AppState.currentState
};
componentDidMount() {
AppState.addEventListener("change", this._handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener("change", this._handleAppStateChange);
}
_handleAppStateChange = nextAppState => {
if (
this.state.appState.match(/inactive|background/) &&
nextAppState === "active"
) {
console.log("App has come to the foreground!");
}
this.setState({ appState: nextAppState });
};
render() {
return (
<View style={styles.container}>
<Text>Current state is: {this.state.appState}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
}
});
export default AppStateExample;
عند عدم الرغبة برؤية انتقال AppState
من الحالة active
إلى الحالة inactive
على منصة iOS يمكن إزالة متغير الحالة واستخدام القيمة appState.current
.
يُظهر المثال السابق دائمًا الإشعار "Current state is: active" فقط، لأنّ التّطبيق يكون مرئيًّا للمستخدم عندما يكون في الحالة الفعّالة فقط؛ أمّا الحالة null
فتحدث لحظيًّا فقط، لذا يُنصح بتجريب المثال على الجهاز الشّخصي بدلًا من المعاينة المضمنة (embedded preview).
الأحداث
change
يُطلَق هذا الحدث عند تغيّر حالة التّطبيق، ويستدعى المُنصت (listener) مع أحد قيم حالات التطبيق الحاليّة (التي ذكرناها في الأعلى).
memoryWarning
يُستخدم هذا الحدث عند الحاجة لإلقاء تحذير الذّاكرة أو إطلاقه.
focus
(يعمل على منصّة Android فقط) ويُطلَق عند تفاعل المستخدم مع التطبيق.
blur
(يعمل على منصّة Android فقط) ويُطلَق عند عدم تفاعل المستخدم مع التّطبيق، وهو مفيد عندما يسدل المستخدم ستار الإشعارات notification drawer
، ولا تتغيّر AppState
لكن يُطلق الحدث blur
.
التوابع
()addEventListener
addEventListener(type, handler);
يضيف معالجًا لتغيرات AppState وذلك بالتنصّت للحدث من النوع change
وربطه مع المعالج (handler).
ملاحظة: أصبحت AppState صنفًا فرعيًّا من NativeEventEmitter، لذا يمكن استبدال التابعين addEventListener
و removeEventListener
بالتابعين addListener
و listener.remove()
مباشرةً. ستحدث تغيرات مفاجئة لأنّ اسم التابع والحدث مختلفان (يجب أن تكون الأحداث addListener
فريدةً بشكلٍ عامٍّ).
removeEventListener()
removeEventListener(type, handler);
يزيل المعالج وذلك بتمرير الحدث من النوع type
والمعالج (handler).
الخاصيات
currentState
AppState.currentState;