Can’t clear a window when using setTimeOut Code Answer

I want to clear setTimeOut() when button clicked, but screen keep log me in directly even when i add clearTimeOut, here is function i use

 function LoginScreen({ navigation, props }) {
  const dispatch = useDispatch()
  const Login = useSelector(state => {
    return state.loginStatus
  })

  function handleLogin() {
    dispatch({ type: 'changeLogin' })
  }
  function handlDefault() {
    dispatch({ type: 'getDefault' })
  }

  let timeID
  function SetTimer() {
    handleLogin()
    timeID=setTimeout(() => {
      navigation.navigate('Home');
    }, 5000)
  }
  function clearTO() {
    clearTimeout(timeID)
    dispatch({ type: 'getDefault' });
    
  }
    

Basically i want after pressing the login button, a Modal window will appear and show the login effect and in that window there is a button that when pressed, the login will be paused, however i can’t stop the setTimeOut, the screen keeps logging in automatically, error like this , please help, thank you a lot

Answer

You can use React.useRef to make this variable timeID never lose its value. You will probably need to handle multiple clicks on the button too, to avoid activating multiple setTimeout.

Observation: You can try a similar logic with useState + useEffect, but it will probably need some useCallback and make the logic more complex

Visual example here: https://snack.expo.io/LYVlrY4_l

import * as React from 'react';
import { Pressable, View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

function Login({ navigation }) {
  const timeIdRef = React.useRef(null)

  React.useEffect(() => {
      return () => {
        if (timeIdRef.current) {
          // make sure this is always cleared in case clearTo is never called
          clearTimeout(timeIdRef.current)
        }
      }
  }, [timeIdRef])

  function handleLogin() {
    console.log('handleLogin')
  }

  function SetTimer() {
    handleLogin();
    if (timeIdRef.current) {
      // clear any previous timeIdRef to avoid multiple button click activate multiple setTimeout
      clearTimeout(timeIdRef.current)
    }
    const timeID = setTimeout(() => {
      navigation.navigate("Home");
    }, 5000);
    timeIdRef.current =  timeID
  }

  function clearTO() {
    clearTimeout(timeIdRef.current);
    timeIdRef.current = null
  }


  return (
    <View style={styles.ViewStyle}>
      <Text style={{ fontSize: 40 }}>Login To System</Text>
      <TouchableOpacity style={{ backgroundColor: 'green', padding: 8}} onPress={SetTimer}>
        <Text>START timer</Text>
      </TouchableOpacity>
       <TouchableOpacity style={{ backgroundColor: 'red', padding: 8}} onPress={clearTO}>
        <Text>STOP timer</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  ViewStyle: {
    alignItems: "center",
    display: "flex",
    flex: 1,
    justifyContent: "center"
  },
});

function Home({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Welcome to Home Screen</Text>
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
     <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Login" component={Login} />
        <Stack.Screen name="Home" component={Home} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

Related Posts

© No Copyrights, All Questions are retrived from public domain.
Tutorial Guruji