Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6287

Proper Timer Behavior using navigating between tab screens (React Native Typescript Hooks)

$
0
0

I am in the early stages of learning react native along with TypeScript and react-navigation. I am trying to implement a countdown timer app with editable time and labels. I was able to get most of the behaviors I'm wanting to work correctly but the last thing I'm stuck on is I want the timer to reset to the input value when the go button is pressed. other comments on the capabilities of the timer are in the comments of app.tsx.

Along with assistance with this functionality, any input on better ways of doing this or more appropriate standards I should have in my code would be appreciated.

link to the snack if that works: https://snack.expo.io/@jpb159/two-tap-timer

app.tsx

// In App.js in a new project// React Navigation v5, Hooks, Interval and Typescript Practice// Timer app counting down in secconds until the time reaches 0// -  Countdown should continue until either time reaches 0 or the 'go' button is pressed.// -  Should reset the 'time' to the entered 'time value' every time the 'go' button is pushed then continue counting down to 0.// -  No reset should happen when tabs are selected using bottomTabNav. // -  Initial timer screen values are id= -1, timerName= "initial name", duration= 0, time= 0.import * as React from 'react';import { Button } from 'react-native';import AppTabs from './src/Navigation'function App() {  return (<AppTabs />  );}export default App;

Navigation.tsx

import React, { useState } from 'react';import { NavigationContainer, RouteProp } from '@react-navigation/native';import { createStackNavigator, StackNavigationProp  } from '@react-navigation/stack';import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';import HomeScreen from '../Screens/HomeScreen';import EditScreen from '../Screens/EditScreen';import TimerScreen, { TimerProps } from '../Screens/TimerScreen';type HomeStackParamList = {  HomeScreen: undefined;  EditScreen: undefined;};type TimerStackParamList = {  TimerScreen: { id:number|undefined, timerName: string; duration: number } | undefined;};type TimerScreenRouteProp = RouteProp<TimerStackParamList, 'Timer Screen'>;type TimerScreenNavigationProp = StackNavigationProp<  TimerStackParamList,'Timer Screen'>;export type NavProps = {  navigation: TimerScreenNavigationProp,  route: TimerScreenRouteProp,};const HomeStack = createStackNavigator<HomeStackParamList>();const TimerStack = createStackNavigator<TimerStackParamList>();function HomeTab({ route } : NavProps) {  return (<HomeStack.Navigator><HomeStack.Screen        name="Home Screen"        component={HomeScreen}        initialParams={{          timerName: "timer 1",        }}      /><HomeStack.Screen name="Edit Screen" component={EditScreen} /></HomeStack.Navigator>  );}function TimerTab({ route } : NavProps) {  const props = route.params.params ?  route.params.params : {id:".params.params undefined",timerName:".params.params undefined", duration:".params.params undefined"}  console.log("--TIMER TAB-\n"+"\t-id: "+props.id+"\t-timerName: "+props.timerName+"\t-duration: "+props.duration  );  return (<TimerStack.Navigator><TimerStack.Screen         name="Timer Screen"         initialParams={{...props, id:-1}}         component={TimerScreen}      /></TimerStack.Navigator>  );}type TabParamList = {  Home: undefined;  Timer:    | {        screen: 'Timer Screen';        params: { timerName: string; duration: number };      }    | undefined;};const Tab = createBottomTabNavigator<TabParamList>();const AppTabs = () => {  return (<NavigationContainer><Tab.Navigator initialRouteName="Home"><Tab.Screen name="Home Tab" component={HomeTab} /><Tab.Screen name="Timer Tab" component={TimerTab}           initialParams={{                        params:{              id: -1,              timerName: "initial name",              duration: 0,              stop: true            }          }}        /></Tab.Navigator></NavigationContainer>  );};export default AppTabs;

Home Screen where the timer name and time are editable and where the go button navigates to the timer screen along with params

import React, { useState } from 'react';import { View, Text, Button, TextInput, Platform } from 'react-native';import { NavProps } from '../src/Navigation';import DateTimePicker from '@react-native-community/datetimepicker';function HomeScreen({ route, navigation }: NavProps) {  const [text, onChangeText] = React.useState<string>();  const [val, onChangeVal] = React.useState<string>();  const [date, setDate] = useState<any>(new Date(1598051730000));  const [mode, setMode] = useState<any>('date');  const [show, setShow] = useState<boolean>(false);  const onChange = (event: any, selectedDate: any) => {    const currentDate = selectedDate || date;    setShow(Platform.OS === 'ios');    setDate(currentDate);  };  const showMode = (currentMode: string) => {    setShow(true);    setMode(currentMode);  };  const showDatepicker = () => {    showMode('date');  };  const showTimepicker = () => {    showMode('time');  };  return (<View      style={{ flex: 1, alignItems: 'center', justifyContent: 'space-evenly' }}><Text>Home Screen</Text><View        style={{          flexDirection: 'column',          width: '90%',          padding: '1%',          borderWidth: 10,        }}><View          style={{            flexDirection: 'row',            width: '90%',            alignItems: 'center',            justifyContent: 'space-evenly',          }}><Text> Label: </Text><TextInput            placeholder="'Timer Name...'"            value={text}            onChangeText={onChangeText}          /></View><View          style={{            flexDirection: 'row',            width: '90%',            alignItems: 'center',            justifyContent: 'space-evenly',          }}><Button onPress={showTimepicker} title="Show time picker!" />          {show && (<DateTimePicker              testID="dateTimePicker"              value={date}              mode={mode}              is24Hour={true}              display="default"              onChange={onChange}            />          )}<Button title="Go"             onPress={() => {              console.log("HOME SCREEN-\n"+"\t-id: "+1+"\t-timerName: "+text+"\t-duration: "+val              );              navigation.navigate('Timer Tab', {                screen: 'Timer Screen',                params:{                  id: 1,                  timerName: text,                  duration: Number(val),                  stop: false                }              });            }}          /></View><View><Text> time value: </Text><TextInput            placeholder="'enter time value...'"            keyboardType="number-pad"            value={val}            onChangeText={onChangeVal}          /></View></View>{/*<Text> other buttons:</Text><Button        title="Timer Screen"        onPress={() => {          console.log('timer duration: '+ route.params.duration),            navigation.navigate('Timer Tab',              {screen:'Timer Screen',                 params:{                  id:0                }               }            );        }}      /><Button        title="Edit Screen"                onPress={() => {          navigation.navigate('Edit Screen');        }}      />*/}      </View>  );}export default HomeScreen;

Timer Screen where the countdown is displayed and should run until 0 (then console.logs 'timer done') or the 'go' button is pressed again resetting the time left

import React, { useEffect, useState } from 'react';import { View, Text, Button } from 'react-native';import { NavProps } from '../src/Navigation';export type TimerProps={  isPaused: boolean,}function TimerScreen({ route, navigation }: NavProps, props: TimerProps) {  const { id, timerName, duration, stop } = route.params;  const [initTime, setInitTime] = useState<number>(duration);  const [time, setTime] = useState<number>(duration);  const [isStopped, setIsStopped] = useState<boolean>(stop);  console.log("----TIMER SCREEN-\n"+"\t-id: "+id+"\t-timerName: "+timerName+"\t-duration: "+duration+"\t-initTime: "+initTime+"\t-stop: "+isStopped  );  useEffect(() => {    if(initTime !== duration){      console.log("***duration changed!!!");       setTime(duration)      setInitTime(duration)    }    console.log('time:'+time);    const timerId = setInterval(() => {      // console.log('time:'+time);      if(!props.isPaused){          setTime(time-1);      }      else{console.log('timer paused: '+props.isPaused)}    }, 1000)    if(time<=0||time === null||time === undefined){       console.log('Timer Done timerId:'+timerId);      setIsStopped(true);      if(timerId) {        // setInitTime(0);        clearInterval(timerId);      }       return;     }    // const unsubscribe = navigation.addListener('focus', () => {    //   console.log('focussed');    //   setTime(route.params.duration);    // });    return () => clearInterval(timerId);  }, [time, duration, initTime, isStopped, props.isPaused,])  return (<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><Text>Timer Screen {"id:"+id}</Text><Text>timerName: {JSON.stringify(timerName)}</Text><Text>duration: {JSON.stringify(duration)}</Text><Text>time: {time}</Text><View></View><Button        title="Timer Screen again"        onPress={() => {          navigation.push('Timer Screen', {            id: Math.floor(Math.random() * 100),          });        }}      /><Button        title="Go to Home"        onPress={() =>          navigation.navigate('Home Tab', { screen: 'Home Screen' })        }      /><Button title="Go back" onPress={() => navigation.goBack()} /><Button        title="Go back to first screen in stack"        onPress={() => navigation.popToTop()}      /></View>  );}export default TimerScreen;

Viewing all articles
Browse latest Browse all 6287

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>