I am using react naviagtion 5 and typescript for my mobile.
I have two sets of data in the database, one is date
and one is time
. Both are expecting strings.
I made one POST
request when the user chooses the date, and that time will be selected for the user. I made a helper function for when the user's choosing time will be over, in which case I show them an alert on the front-end that shows
"Your selected time expired!"
After showing that Alert. I forcefully clear the delivery time. My logic works fine. But I am having issue that when I am in the same screen or minimise the app, the useEffect
does not trigger. If I go different screen and come back to that delivery screen then it triggers. I don't know how to hot reload the app when selecting time expired even though I am in the same screen or minimise the app.
I share my code in Expo snack
This is my sample code
import * as React from 'react';
import {Text,View, Alert, Button} from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { useNavigation } from '@react-navigation/native';
const Stack = createStackNavigator();
const deliveryDate = "2021-06-21";
const deliveryTime = "10:00-10:03";
const isTimeWindowExpired = (date: string, time: string) => {
const [startTime] = time.split('-');
const newDate = new Date(`${date}T${startTime}`);
if (newDate.getTime() < new Date().getTime()) {
return true;
}
return false;
};
function Home() {
const navigation = useNavigation()
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('details')}
/>
</View>
);
}
function SecondHome() {
const navigation = useNavigation()
React.useEffect(() => {
const isExpired = isTimeWindowExpired(deliveryDate, deliveryTime);
const expirationTrigger = () => {
Alert.alert("Time Expired");
};
if (isExpired) {
expirationTrigger();
}
}, [deliveryDate, deliveryTime]);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>useEffect does not trigger when it's in same screen or minimisse</Text>
<Text>Home</Text>
<Button
title="Go back Home"
onPress={() => navigation.goBack()}
/>
</View>
);
}
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="home" detachInactiveScreens>
<Stack.Screen name="home" component={Home} />
<Stack.Screen name="details" component={SecondHome} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
Using useIsFocused
hook from react-navigation could help you.
It basically checks, if the screen is looked at. Adding it into useEffect
and its dependencies, the useEffect
will trigger every time isFocused
changes its value. When you leave the screen (to another screen or minimizing the app) it's false
and when you come back, it is true
back again.
import { useIsFocused } from '@react-navigation/native';
function SecondHome() {
const navigation = useNavigation()
const isFocused = useIsFocused();
React.useEffect(() => {
if(isFocused) {
const isExpired = isTimeWindowExpired(deliveryDate, deliveryTime);
const expirationTrigger = () => Alert.alert("Time Expired");
if (isExpired) {
expirationTrigger();
}
}
}, [deliveryDate, deliveryTime, isFocused]);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>useEffect does not trigger when it's in same screen or minimisse</Text>
<Text>Home</Text>
<Button
title="Go back Home"
onPress={() => navigation.goBack()}
/>
</View>
);
}
You can read more about it here https://reactnavigation.org/docs/use-is-focused/