اذهب إلى المحتوى

السؤال

نشر

أعمل على تطبيق React Native و واجهتني مشكلة بسيطة. لنفرض أن الشاشة الرئيسية للتطبيق هي ال feed screen و أنا حاليًا أتفقد صفحتي الشخصية، عندما أقوم بنقل التطبيق ليعمل في الخلفية و أتصفح باقي التطبيقات و بعدها أعود لفتح التطبيق الخاص بي ينقلني إلى ال feed screen بدلًا من ال profile screen

ما هي الحلول المقترحة لهذا الأمر؟

-- أستخدم React Contect API 

const[isReady, setIsReady] = useState(false);
const[user,setUser]=useState();
const[authenticated,setAuthenticated]=useState();
const appState = useRef(AppState.currentState);
const [appStateVisible, setAppStateVisible] =useState(appState.current);

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

 useEffect(() => {
 AppState.addEventListener("change", _handleAppStateChange);
  return () => {
  AppState.removeEventListener("change", _handleAppStateChange);
  };
  }, []);

const restoreUser = async () => {
const user = await storage.getUser();
if (user) setUser(user);
};

if (!isReady)
return (
<AppLoading 
startAsync={restoreUser} 
onFinish={() => setIsReady(true)} 
onError={console.warn}
/>
);  

return(
 (appState.current)==='active'?
 <AuthContext.Provider value= 
 {{user,setUser,authenticated,setAuthenticated}}>
 <NavigationContainer theme={navigationTheme} ref={navigationRef}>
   {
   (user&&authenticated)?<AppNavigator/>
   :(user)?<PasscodeNavigator/>
   :<AuthNavigator/>
   }
 </NavigationContainer>
 </AuthContext.Provider>
 :
 <SplashScreen/>

 

Recommended Posts

  • 0
نشر

لنتمكن من حفظ حالة التحرك في التطبيق، يمكننا استخدام onStateChange و initialState الموجودين لدى الحاوية (NavigationContainer).

  • onStateChange تُعلمنا هذه الخاصية بأية تغييرات في الحالة، لذا يمكننا حفظ الحالة بداخلها.
  • initialState تسمح لنا هذه الخاصية بتمرير حالة أولية، لذا يمكننا تمرير الحالة المستعادة بداخلها.

ضع في اعتبارك أن الحالة تتم استعادتها بشكل غير متزامن (Asynchronous)، فعلينا اولاً ان نكتب مكون التحميل وحالته بهذا الشكل:

import Loading from '../Loading';

if (!isReady) {
	return <Loading />;
}

سنقوم ايضاً بكتابة الثابت PERSISTENCE_KEY الذي سيستخدم لحفظ حالة التحرك عن طريق AsyncStorage. فمثلاً، عن تغير الحالة، سنكتب الدالة بداخل onStateChange هكذا:

<NavigationContainer
	onStateChange={(state) =>
		AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))
	}
></NavigationContainer>

والآن الجزء الاهم هو الدورة التي سنكتبها بداخل useEffect والتي ستكون بالشكل التالي:

const [isReady, setIsReady] = React.useState(false);

React.useEffect(() => {
	const restoreState = async () => {
		try {
			const initialUrl = await Linking.getInitialURL();

			if (Platform.OS !== 'web' && initialUrl == null) {
				const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY);
				const state = savedStateString ? JSON.parse(savedStateString) : undefined;

				if (state !== undefined) {
					setInitialState(state);
				}
			}
		} finally {
			setIsReady(true);
		}
	};

	if (!isReady) {
		restoreState();
	}
}, [isReady]);

يوجد ايضاً طريقة آخرى عن طريق استخدام مكون الـ Modal من React Native، حيث يمكننا إظهار Splash بداخله عندما تتغير حالة التطبيق:

function App() {
  const [isModalVisible, setIsModalVisible] = React.useState(false);

  const handleStateChange = nextState => {
    if (state.current.match(/inactive|background/) && nextState === 'active') {
      setIsModalVisible(false);
    } else {
      setIsModalVisible(true);
    }
  };

  return (
    <React.Fragment>
    	<AuthContext.Provider>
    		<NavigationContainer>
				{/* ضع باقي التحويلات هنا */}
    			<Modal animationType="slide" visible={isModalVisible} transparent={true}>
    				<Splash />
    			</Modal>
    		</NavigationContainer>
    	</AuthContext.Provider>
    </React.Fragment>
  );
}

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...