I have to make a countdown timer in an react-native app but i dont know how, i already looked it up and and found some librarys such as react-native-countdown component but it didnt worked as id like, and got some other solutions like setInterval but i dont know how to implement it in my code and make it display on the screen as in the images below:
The time goes from 00:00 to 60:00 (MM:SS) as the user slides the bar, that changes the number 05:00 by 05:00, ive already done that but with a static number, i couldnt make it countdown.
Heres how my code is looking right now:
import { useNavigation } from '#react-navigation/core';
import React, { useEffect, useState } from 'react';
import { SafeAreaView, Text, Image, TouchableOpacity, StyleSheet, Dimensions, TextInput, KeyboardAvoidingView, Platform, View } from 'react-native';
import Slider from '#react-native-community/slider';
import CountDown from 'react-native-countdown-component';
import abacatezinImg from '../assets/abacatezinin.png';
import botaoStop from '../assets/botaoStop.png';
import botaoPlay from '../assets/botaoPlay.png';
export function Timer(){
const [range, setRange] = useState('0');
const [sliding, setSliding] = useState('Inactive');
const [isSecureEntry,setIsSecureEntry]=useState(true);
const navigation = useNavigation<any>();
function handleQuit(){
navigation.navigate('Quit');
}
if(isSecureEntry){
return(
<SafeAreaView style={styles.container}>
<Text style={styles.texto}>{range}</Text>
<View style={styles.container2}>
<Slider
style={styles.slider}
minimumValue={0}
maximumValue={60}
minimumTrackTintColor='#7E9F70'
maximumTrackTintColor='#A7C99A'
thumbImage={abacatezinImg}
value={30}
onValueChange={value => setRange(parseInt(value) + ':00')}
onSlidingStart={() => setSliding('Sliding')}
onSlidingComplete={() => setSliding('Inactive')}
step={5}
/>
<TouchableOpacity onPress={() =>{
setIsSecureEntry((prev)=> !prev)
}}>
<Image source={botaoPlay} style={styles.bPlay}/>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
else{
return(
<SafeAreaView style={styles.container}>
<Text style={styles.texto}>{range}</Text>
<View style={styles.container3}>
<TouchableOpacity onPress={handleQuit}>
<Image source={botaoStop} style={styles.bStop}/>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
alignItems: 'center',
justifyContent: 'flex-start',
},
container2:{
backgroundColor: '#E4F0E2',
alignItems: 'center',
justifyContent: 'space-between',
flexDirection: 'row',
borderRadius: 100,
width: 327,
height: 66,
paddingHorizontal: 19,
marginTop: 20,
},
container3:{
alignItems: 'center',
justifyContent:'space-between',
marginTop: 20,
},
slider:{
width: 209,
height: 50,
transform: [{scaleY: 4}]
},
bPlay:{
width: 50,
height: 50,
},
bStop:{
width: 66,
height: 66,
},
texto:{
fontWeight: '300',
fontSize: 58,
lineHeight: 87,
letterSpacing: 0.03,
color: '#1B3810',
},
})
If anyone has any idea how to make it Id appreciate the help
Hooks(using useEffect) to countdown using setInterval in react - native:
const [timerCount, setTimer] = useState(60)
useEffect(() => {
let interval = setInterval(() => {
setTimer(lastTimerCount => {
if (lastTimerCount == 0) {
//your redirection to Quit screen
} else {
lastTimerCount <= 1 && clearInterval(interval)
return lastTimerCount - 1
}
})
}, 1000) //each count lasts for a second
//cleanup the interval on complete
return () => clearInterval(interval)
}, []);
use the state variable timerCount as:
<Text>{timerCount}</Text>
Related
I'm new to react native and trying to create a button, here is my StartScreen:
import React from 'react' import Background from '../components/Background' import AppButton from '../components/AppButton'
export default function StartScreen({ navigation }) {
return(
<Background>
<AppButton title="HEEEY!" size="sm" backgroundColor="#007bff" />;
</Background>
) }
Here is my AppButton:
import React from 'react'
import { StyleSheet, TouchableOpacity, Text } from "react-native";
export default function AppButton ({ onPress, title, size, backgroundColor }) {
return (
<TouchableOpacity
onPress={onPress}
style={[
styles.appButtonContainer,
size === "sm" && {
paddingHorizontal: 8,
paddingVertical: 6,
elevation: 6
},
backgroundColor && { backgroundColor }
]}
>
<Text style={[styles.appButtonText, size === "sm" && { fontSize: 14 }]}>
{title}
</Text>
</TouchableOpacity>
)
};
const styles = StyleSheet.create({
screenContainer: {
flex: 1,
justifyContent: "center",
padding: 16
},
appButtonContainer: {
elevation: 8,
backgroundColor: "#009688",
borderRadius: 10,
paddingVertical: 10,
paddingHorizontal: 12
},
appButtonText: {
fontSize: 18,
color: "#fff",
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase"
}
});
Here is my Background:
import React from 'react'
import { ImageBackground, StyleSheet, KeyboardAvoidingView } from 'react-native'
import { theme } from '../core/theme'
export default function Background({ children }) {
return (
<ImageBackground style={styles.background}>
<KeyboardAvoidingView style={styles.container} behavior="padding">
{children}
</KeyboardAvoidingView>
</ImageBackground>
)
}
const styles = StyleSheet.create({
background: {
flex: 1,
width: '100%',
backgroundColor: theme.colors.surface,
},
container: {
flex: 1,
padding: 20,
width: '100%',
maxWidth: 340,
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
},
})
When I try to run the application in my Android phone I get the following error:
Error: Text strings must be rendered within a component.
Blockquote
But I cant figure out where this error happens. Can someone spot the mistake?
You have an unnecessary semicolon (;) in your StartScreen JSX, remove it.
export default function StartScreen({ navigation }) {
return(
<Background>
<AppButton title="HEEEY!" size="sm" backgroundColor="#007bff" />
</Background>
); }
This is an example code as I'm trying to learn Animated from react native. If I want to press a button and double the size of this text smoothly, how would I do that? From what I understood I need to add Transform: scale x/y somehow but I'm super confused by this. Thanks
import React, { useRef, useEffect } from 'react';
import { Animated, Text, View } from 'react-native';
const FadeInView = (props) => {
const fadeAnim = useRef(new Animated.Value(0)).current
useEffect(() => {
Animated.timing(
fadeAnim,
{
toValue: 1,
duration: 2000,
useNativeDriver: true
}
).start();
}, [])
return (
<Animated.View style={{...props.style, opacity: fadeAnim}}>
{props.children}
</Animated.View>
);
}
export default () => {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<FadeInView>
<Text style={{fontSize: 28, textAlign: 'center', padding: 10}}>Fading in</Text>
</FadeInView>
</View>
)
}
Let's say you want to scale the text when it's clicked. You can do this:
export default () => {
const scaleAnim = useRef(new Animated.Value(1)).current;
const animateTextSize = () => {
Animated.timing(
scaleAnim,
{
toValue: 2,
duration: 2000,
useNativeDriver: true
}
).start();
}
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<FadeInView>
<Animated.Text style={{fontSize: 28, textAlign: 'center', padding: 10, transform:[{scale:scaleAnim}]}} onPress={animateTextSize}>Fading in</Animated.Text>
</FadeInView>
</View>
)}
snack demo
I am about to making an app with React Native and I have three screens with deferent styles (themes). I want to navigate among these three screens, So I am passing data from my main screen (App.js) as parent to the other three as child (screen1, screen2, screen3). I used a modal which has three button in it and i want whenever I pressed one of them, the screen change to the pressed one. This is my App.js file
import React, { useState, useEffect } from "react";
import { StyleSheet, View } from "react-native";
import Screen1 from "./screens/CalcScreen";
import Screen2 from "./screens/Screen1";
import Screen3 from "./screens/Screen2";
export default function App() {
const [whiteScreen, setWhiteScreen] = useState(false);
const [darkScreen, setDarkScreen] = useState(false);
const [pinkScreen, setPinkScreen] = useState(false);
const whiteScreenHandler = () => {
setWhiteScreen(true);
setDarkScreen(false);
setPinkScreen(false);
};
const darkScreenHandler = () => {
setDarkScreen(true);
setWhiteScreen(false);
setPinkScreen(false);
};
const pinkScreenHander = () => {
setPinkScreen(true);
setWhiteScreen(false);
setDarkScreen(false);
};
let content = <screen1 setDarkScreen={darkScreenHandler} />;
let content2 = <Screen2 setWhiteScreen={whiteScreenHandler} />;
let content3 = <Screen3 setPinkScreen={pinkScreenHander} />;
if (darkScreen) {
content = content;
} else if (whiteScreen) {
content = content2;
} else if (pinkScreen) {
content = content3;
}
return <View style={styles.container}>{content}</View>;
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#374351",
},
});
And this is one of my screens and my modals in my screens, the other two screens are same in coding but not in styles and I used this modal in each three screens,(does it right to use in three screens?) anyway whenever I'm pressing modal's button to change the screens i got props.screen handler() is not a function. What is wrong in my code?
import React, { useState } from "react";
import {
StyleSheet,
Text,
ScrollView,
View,
TouchableOpacity,
Alert,
Animated,
Modal,
Pressable,
} from "react-native";
const Screen1 = (props) => {
return (
<View style={styles.screen}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<View style={styles.button}></View>
<Text style={styles.modalText}>Themes</Text>
<TouchableOpacity
style={styles.darkTheme}
onPress={() => {
props.setDarkScreen();
}}
>
<Text>Dark</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.whiteTheme}
onPress={() => {
props.setWhiteScreen();
}}
>
<Text>White</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.pinkTheme}
onPress={() => {
props.setPinkScreen();
}}
>
<Text>Pink</Text>
</TouchableOpacity>
<Pressable
style={[styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>X</Text>
</Pressable>
</View>
</View>
</Modal>
<Pressable
style={[styles.button, styles.buttonOpen]}
onPress={() => setModalVisible(true)}
>
<Text style={styles.openText}>{">"}</Text>
</Pressable>
</View>
)
}
const styles = StyleSheet.create({
screen: {
backgroundColor: "#fafcff",
},
centeredView: {
// flex: 1,
marginStart: 15,
justifyContent: "center",
alignItems: "center",
// marginTop: 70,
},
modalView: {
marginTop: 200,
backgroundColor: "rgba(255,255,255,0.5)",
borderRadius: 20,
padding: 20,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.5,
shadowRadius: 4,
elevation: 5,
},
button: {
borderRadius: 15,
padding: 10,
elevation: 2,
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
buttonOpen: {
backgroundColor: "rgba(1,143,132,0.6)",
position: "absolute",
marginTop: 45,
marginStart: -25,
elevation: 2,
height: 70,
width: 40,
},
buttonClose: {
backgroundColor: "rgba(1,1,1,1)",
height: 40,
width: 40,
borderRadius: 50,
// padding: 10,
elevation: 2,
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
textStyle: {
color: "white",
// fontWeight: "bold",
textAlign: "center",
},
modalText: {
marginBottom: 10,
textAlign: "center",
},
openText: {
fontSize: 25,
fontWeight: "bold",
color: "white",
textAlign: "right",
},
});
export default Screen1;
You can easily doing that by using "React Native Navigation". Here is the documentation:
https://reactnavigation.org/docs/getting-started. I also recommend you that you might want to create your screens into different files to make your code cleaner.
Good evening,
I have been trying to create custom card Component in react native that i can use everywhere i need it.
I apply a part of the style inside the component itself, and for the width, layout etc, where i need it. Then i am trying to use the spread operator to "merge" all the properties in the style of the child component. I saw it in a video tutorial, but it's not working for me, and i don't see what is wrong in my code :
import React from 'react';
import { View, Text, StyleSheet, TextInput, Button } from 'react-native';
import Card from '../components/Card';
import Color from '../constants/colors'
import Input from '../components/Input'
const StartGameScreen = props => {
return (
<View style={styles.screen}>
<Text style={styles.title}>Start a New Game!</Text>
<Card style={styles.inputContainer}>
<Text>Select a Number</Text>
<Input />
<View style={styles.buttonContainer}>
<Button title="Reset" color={Color.accent} onPress={() => {}} />
<Button title="Confirm" color={Color.primary} onPress={() => {}} />
</View>
</Card>
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
padding: 10,
alignItems: 'center'
},
title: {
fontSize: 20,
marginVertical: 10
},
inputContainer: {
width: 300,
maxWidth: '80%',
alignItems: 'center',
},
buttonContainer: {
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
paddingHorizontal: 15
},
input: {
width: 50
}
});
export default StartGameScreen;
And the child component :
import React from 'react';
import { View, StyleSheet } from 'react-native';
const Card = props => {
return (
<View style={{ ...styles.card, ...props.style }}> {props.children}</View>
);
};
const styles = StyleSheet.create({
card: {
shadowColor: 'black',
shadowOffset: { width: 0, height: 2 },
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 8,
backgroundColor: 'white',
padding: 20,
borderRadius: 10
}
});
export default Card;
Note : I tried with input and card, it's working for none of them.
Is that something that we were able to do but we can't anymore ?
Thank you
Have a nice weekend
Try this:
const Card = props => {
return (
<View style={[styles.card, props.style ]}> {props.children}</View>
);
};
I am a beginner in react native and I am trying to make a quiz app by using states and functions to check if the button pressed is the correct option based on the word given. However, I have received this error about invariant violation: Maximum update depth exceeded, could this be due to the way I use onPress?
import React, {Component} from 'react';
import {
View,
Text,
SafeAreaView,
TouchableOpacity,
Image,
ScrollView,
StyleSheet,
} from 'react-native';
import {color} from 'react-native-reanimated';
import Ionicons from 'react-native-vector-icons/Ionicons';
import {createAppContainer} from 'react-navigation';
import {createBottomTabNavigator} from 'react-navigation-tabs';
import {createStackNavigator} from 'react-navigation-stack';
const styles = StyleSheet.create({
progressbar: {
width: 218,
height: 24,
borderRadius: 12,
borderColor: 'grey',
borderWidth: 1,
marginTop: 70,
paddingRight: 79,
paddingLeft: 79,
},
words: {
fontFamily: 'Arial',
fontSize: 85,
fontWeight: 'bold',
},
image: {width: 345, height: 391, borderRadius: 50, marginTop: 31},
button: {width: 100, height: 80, borderRadius: 29, marginHorizontal: 5},
});
export default class quizC extends React.Component {
state = {
progress: 0,
progressbar: 0,
progressbarwidth: 0,
words: '',
imagesource: '',
option: 0,
option1: '',
option2: '',
option3: '',
correctoption: 0,
score: 0,
};
_updateProgress() {
switch (this.state.imagesource) {
case 1:
this.setState({words: 'c_t'});
this.setState({progressbarwidth: 109});
this.setState({correctoption: 2});
this.setState({option1: 'c'});
this.setState({option2: 'a'});
this.setState({option3: 't'});
//return cat
break;
case 2:
this.setState({words: 'do_'});
this.setState({progressbarwidth: 218});
this.setState({correctoption: 3});
this.setState({option1: 'd'});
this.setState({option2: 'o'});
this.setState({option3: 'g'});
//return dog
break;
}
}
_checkcorrectans() {
if (this.state.option == this.state.correctoption) {
this.setState(prevState => ({progress: prevState.progress + 1}));
this.setState(prevState => ({score: prevState.score + 1}));
this.setState({imagesource: this.state.progress});
} else {
this.setState(prevState => ({progress: prevState.progress + 1}));
this.setState({imagesource: this.state.progress});
}
}
option1() {
this.setState({option: 1});
this._checkcorrectans();
this._updateProgress();
}
option2() {
this.setState({option: 2});
this._checkcorrectans();
this._updateProgress();
}
option3() {
this.setState({option: 3});
this._checkcorrectans();
this._updateProgress();
}
render() {
return (
<SafeAreaView>
<View style={styles.progressbar}>
<View
style={{
height: 24,
borderRadius: 12,
backgroundColor: 'green',
width: this.state.progressbarwidth,
}}
/>
</View>
<View style={{alignItems: 'center', marginTop: 12}}>
<Text style={styles.words}>{this.state.words}</Text>
</View>
<View style={styles.image}>
<Image src={this._updateProgress()} />
</View>
<View style={{paddingLeft: 23, paddingRight: 23, flexDirection: 'row'}}>
<TouchableOpacity onPress={this.option1()}>
<View style={styles.button}>
<Text>{this.state.option1}</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.option2()}>
<View style={styles.button}>
<Text>{this.state.option2}</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.option3()}>
<View style={styles.button}>
<Text>{this.state.option3}</Text>
</View>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
}
Try using
onPress={() => this.option1()} which is an anonymous function first and the calls option1 or onPress={ this.option1} . These will prevent re-rendering.
This error is due to when you call onPress={this.option1()} , it calls the function and causes the app to re-render which again causes function to be invoked, and hence an infinite loop. The best way would be calling it directly without parentheses onPress={this.option1} or create an anonymous function onPress={() => this.option1()}, which gets executed only once
hope it helps. feel free for doubts
Replace all of onPress method
from:
onPress={this.option1()}
To :
onPress={() => this.option1()}