您好,我刚刚开始使用 React Native 和 Expo 开发移动应用程序。我正在制作一个简单的计时器应用程序,它应该倒数到 0,您可以暂停、恢复和停止计时器。我目前遇到了一个问题,但无法弄清楚问题是什么。
这是问题的简短视频,计时器按预期倒计时,但resumeTimer()函数似乎没有正确更新状态,并且仍然假设它具有“恢复”状态,即使它已经切换到某个状态别的。与 SecondsLeft 状态相同,每次我将其设置为 0 时都会重置。
这是组件的代码:
// Imports //
import {
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
import { useState } from "react";
import Ionicons from "react-native-vector-icons/Ionicons";
import { AnimatedCircularProgress } from "react-native-circular-progress";
import TimeConverter from "../modules/TimeConverter";
import DateTimePicker from "@react-native-community/datetimepicker";
export default function Timer() {
// State //
const startingSeconds = 22;
const [secondsLeft, setSecondsLeft] = useState(startingSeconds);
const [state, setState] = useState("pause");
// Functions //
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
const resumeTimer = async (secLeft) => {
if (state == "resume" && secLeft > 0) {
await sleep(1000);
if (state == "resume") {
setSecondsLeft(secLeft - 1);
resumeTimer(secLeft - 1);
}
}
};
const pauseTimer = () => {
setState("pause");
};
const stopTimer = () => {
setState("stop");
setSecondsLeft(0);
};
return (
<View style={styles.container}>
<View style={styles.topBar}>
<Text style={styles.topBarTitle}>State: {state}</Text>
</View>
<View style={styles.timerContainer}>
<AnimatedCircularProgress
style={{ position: "absolute" }}
size={300}
width={5}
fill={(secondsLeft / startingSeconds) * 100}
tintColor="red"
onAnimationComplete={() => console.log("onAnimationComplete")}
backgroundColor="white"
/>
<TouchableOpacity disabled={state == "resume" ? true : false}>
<View style={styles.timerCircle}>
<Text style={styles.timerText}>
{TimeConverter.secondsToTimerString(secondsLeft)}
</Text>
</View>
</TouchableOpacity>
</View>
<View style={styles.bottomBar}>
<TouchableOpacity>
<Ionicons
style={styles.bottomBarItem}
name={"pause-outline"}
size={60}
color={"white"}
onPress={() => {
pauseTimer();
}}
/>
</TouchableOpacity>
<TouchableOpacity>
<Ionicons
style={styles.bottomBarItem}
name={"play-outline"}
size={60}
color={"white"}
onPress={() => {
setState("resume");
resumeTimer(secondsLeft);
}}
/>
</TouchableOpacity>
<TouchableOpacity>
<Ionicons
style={styles.bottomBarItem}
name={"stop-outline"}
size={60}
color={"white"}
onPress={() => {
stopTimer();
}}
/>
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "space-between",
backgroundColor: "#423D6A",
},
topBar: {
flex: 0.13,
backgroundColor: "#423D6A",
alignItems: "center",
justifyContent: "flex-end",
borderColor: "white",
borderBottomWidth: 1,
borderBottomLeftRadius: 25,
borderBottomRightRadius: 25,
},
topBarTitle: {
fontSize: 30,
color: "white",
marginBottom: 10,
},
bottomBar: {
flex: 0.2,
backgroundColor: "#423D6A",
flexDirection: "row",
borderTopLeftRadius: 25,
borderTopRightRadius: 25,
justifyContent: "space-evenly",
alignItems: "center",
borderColor: "white",
borderTopWidth: 1,
},
bottomBarItem: {
marginBottom: "5%",
},
timerContainer: {
flex: 0.67,
marginTop: "10%",
justifyContent: "center",
alignItems: "center",
},
timerCircle: {
width: 250,
height: 250,
borderRadius: 250 / 2,
backgroundColor: "pink",
justifyContent: "center",
alignItems: "center",
},
timerText: {
fontSize: 40,
},
});
我什至不知道从哪里开始调试,因为我不明白这个问题。我希望得到一个解释,为什么它的行为不像我预期的那样。
更新此行 const [secondsLeft, setSecondsLeft] = useState(22);