Reputation: 793
I have a react native project and i have to implement a feature that when app is inactive it renders a logo screen and when app is active it renders the app.
I was able to accomplish this but my problem now is eg. if my main screen is the home screen and i am currently on my profile screen when i navigate between my app and another app then go back to my app i return to the home screen instead of the profile screen.
How do i fix this?
Should i save the current state on my app in AsyncStorage?
I am also using React Context API not redux.
Here is my code as requested:
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/>
Upvotes: 1
Views: 3053
Reputation: 196
I see your problem, you have another option, apart from saving state in AsyncStorage, you could wrap all app in one Navigation Container and redirect using navigation reference.
example:
const { StyleSheet } = require('react-native');
const App = () =>{
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(
<AuthContext.Provider value=
{{user,setUser,authenticated,setAuthenticated}}>
<NavigationContainer theme={navigationTheme} ref={navigationRef}>
{
(user&&authenticated)?<AppNavigator/>
:(user)?<PasscodeNavigator/>
:<AuthNavigator/>
}
</NavigationContainer>
{ (appState.current)!=='active' && <View style={StyleSheet.absoluteFillObject}><SplashScreen/></View> }
</AuthContext.Provider>
)
}
Upvotes: 0
Reputation: 3636
you can show/hide Splash in modal instead of screen when app status change
import { Modal } from "react-native";
const [modalVisible, setModalVisible] = useState(false);
const _handleAppStateChange = nextAppState => {
if (
appState.current.match(/inactive|background/) &&
nextAppState === 'active'
) {
setModalVisible(false);
} else {
setModalVisible(true);
}
};
return (
<>
<AuthContext.Provider
value={{ user, setUser, authenticated, setAuthenticated }}
>
<NavigationContainer theme={navigationTheme} ref={navigationRef}>
{user && authenticated ? (
<AppNavigator />
) : user ? (
<PasscodeNavigator />
) : (
<AuthNavigator />
)}
</NavigationContainer>
</AuthContext.Provider>
<Modal animationType="slide" transparent={true} visible={modalVisible}>
<SplashScreen />
</Modal>
</>
);
Upvotes: 1