Reputation: 2068
I know this question already exists on Stack Overflow but most questions and answers are very old. I am working on an app that performs a fetch call to a db inside componentDidMount obviously using react-native.
I have an interval running in componentDidMount that calls a query and it works well. Now I need to call clearInterval(this.interval)
inside componentWillUnmount to stop the query and logging in my app.
It should be called when I press a save button and navigate with props.navigation.navigate("new Screen", {params})
I read a solution for this where I should use props.navgiation.replace("Screen")
- but it doesn't work for me
The second important part is that componentWillUnmount also needs to be called when I press on another tab (using bottom-tab-navigator)
I understand that the screens in a stack navigator for example never really unmount. So is there a different way to call componentWillUnmount maybe something like when the user left screen( or loses focus on-screen) or user left the specific routeName or something.
My componentWillUnmount - really simple:
componentWillUnmount(){
clearInterval(this.interval)
console.log("Component did Unmount")
}
it's only called if I go to my LogOut Screen and log-out to be in my LoginScreen again.
(EDIT) My Navigator:
const EintragenStack = createStackNavigator(
{
Eintragen: {
screen: StundenEintragen2,
navigationOptions: {
headerTitle: "Stundenverwaltung",
headerTitleStyle:{
color: "white",
alignSelf: "center"
},
headerStyle:{
backgroundColor: "#a51717"
},
}
}
}
)
const CheckStack = createStackNavigator(
{
Übersicht: StundenChecken,
Monat: Monatsübersicht2, // Monatsübersicht
Tag: TagesübersichtDiff, // Tagesübersicht
Edit: {
screen: StundenEdit,
navigationOptions:{
headerTitle: "Stunden bearbeiten",
headerTitleStyle: {
color: "white",
alignSelf: "center"
},
headerStyle: {
backgroundColor: "#F39237"
}
}
}
},
{
backBehavior: "history"
}
);
const Tabs = createBottomTabNavigator(
{
Eintragen: EintragenStack, // StundenEintragen
Checken: CheckStack,
Logout: Logout
},
{
backBehavior: "history",
tabBarOptions: {
labelStyle: {
fontSize: 12,
color: "black"
},
activeTintColor: "red",
activeBackgroundColor: "#ccc"
}
}
);
const AppNavigator = createSwitchNavigator({
Login: Auth, //SecondAuth,
Tabs: Tabs,
});
EintragenStack.navigationOptions = {
tabBarIcon: () => {
return <Icon style={{marginTop: 5}} size={34} name="ios-add-circle-outline" color="green" />;
}
};
CheckStack.navigationOptions = {
tabBarIcon: () => {
return <Icon style={{marginTop: 5}} size={34} name="ios-calendar" color="black" />;
}
};
Logout.navigationOptions = {
tabBarIcon: () => {
return <Icon style={{marginTop: 5}} size={34} name="ios-power" color="red" />;
}
};
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer;
I actually kind of fixed it for my needs but the problem still exists overall. I don't know if this is a good approach but for me I did it like this:
checkUnlockHandler
in componentWillMount
every 30sec.checkUnlockHandler
gets to an if that tells it that it doesn't need running anymore I call clearInterval(this.interval("here is my checkUnlockHandler"))
componentDidMount
stops running which is good.componentDidMount
wrapped in a interval and inside this function to tell when the interval should stop.Upvotes: 5
Views: 3647
Reputation: 56
I faced the same problem in using bottom tab navigator and I found simple solution, which works for me.
componentDidMount()
{
this.props.navigation.addListener('focus', async () =>{
this.interval= setInterval(() => {
//---------
}, 5000);
});
this.props.navigation.addListener('blur', () => {
clearInterval(this.interval);
});
}
also in functional component we can use useEffect with cleanup.
React.useEffect(() => {
navigation.addListener('focus', () => {
this.interval= setInterval(() => {
//---------
}, 5000);
});
return () =>{
clearInterval(this.interval);
};
}, [navigation]);
Upvotes: 4