I created a stack structure here. As you can see, I made a timer with a Setinterval function in Home.js. The Setinterval function works in Home.js, but it continues to work when I go to the Details page. How can I make it stop when I switch to the Details page?
Router.js
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Home from "./components/Home"
import Details from "./components/Details"
import Other from "./components/Other"
const Stack = createStackNavigator();
const Router= ()=> {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{gestureEnabled:true}} >
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Details" component={Details} />
<Stack.Screen name="Other" component={Other} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default Router
Home.js
import React, {useState, useEffect} from 'react';
import {Text, View, Button,StatusBar} from 'react-native';
const Home = ({navigation}) => {
const [timer, setTimer] = useState(1);
useEffect(()=>{
const myTimer=setInterval(()=>{
setTimer(timer=>timer+1)
},2000)
return ()=>clearInterval(myTimer)
})
console.log("timer :",timer)
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<StatusBar hidden/>
<Text>Home</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
};
export default Home;
Details.js
import React,{useState,useEffect} from 'react';
import {Text,View,Button} from "react-native"
const Details = ({ navigation }) => {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Other..."
onPress={() => navigation.navigate('Other')}
/>
</View>
);
}
export default Details;
any help is appreciated
An example of using a React ref to hold the timer ref. It can be cleared in the button's onPress
callback handler. I think a related issue is that the useEffect
hook hasn't any dependencies and the callback updates state, so it triggers rerenders (though the cleanup function should handle this case). Either way, typically when setting up interval timers you only set them up once when the component mounts, clearing the timer when it unmounts.
import React, { useState, useEffect, useRef } from 'react';
import {Text, View, Button,StatusBar} from 'react-native';
const Home = ({ navigation }) => {
const [timer, setTimer] = useState(1);
const timerRef = useRef(null);
useEffect(()=>{
timerRef.current = setInterval(() => setTimer(timer => timer + 1), 2000)
return () => clearInterval(timerRef.current)
}, []); // <-- setup interval only once when component mounts
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<StatusBar hidden/>
<Text>Home</Text>
<Button
title="Go to Details"
onPress={() => {
navigation.navigate('Details');
clearInterval(timerRef.current); // <-- clear interval on navigation
}}
/>
</View>
);
};