这是React Native中的正常计时器
countDown函数出了点问题,我已经试着找了好几个小时了。
我逐行检查useEffect函数是否正确,convertingTotalTime也工作正常。
一定是setState函数有问题,因为它们不是同步的,但是CountDown函数每秒都会被调用,你可以试试代码片段...
你能帮我理解一下代码有什么问题吗?
import React, { useEffect, useState } from "https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js";
import { Button, StyleSheet, Text, View } from "https://cdnjs.cloudflare.com/ajax/libs/react-native-web/0.17.1/index.js";
export default function App() {
const [totalTime, setTotalTime] = useState(50000);
const [playMode, setPlayMode] = useState(false);
const [progress, setProgress] = useState(100);
const [timeString, setTimeString] = useState(`00 : 00`);
const [second, setSec] = useState(0);
const [minute, setMin] = useState(0);
useEffect(() => {
if (playMode && totalTime > 0) {
let myInterval = setInterval(() => {
countDown();
console.log("countdown");
return () => {
clearInterval(myInterval);
};
}, 1000);
}
}, [playMode]);
const countDown = () => {
// console.table(hour, minute, second);
let [sec, min] = [second, minute];
let _totalTime = totalTime;
_totalTime = _totalTime - 1000;
sec = sec - 1;
if (sec == 0 && min >= 1) {
min = min - 1;
}
if (min == 0 && sec == 0) {
// coundown finished
console.warn("counter must stop");
}
setSec((prevState) => sec);
setMin((prevState) => min);
setTotalTime((prevState) => _totalTime);
setTimeString(
`${min < 10 ? "0" + min : min} : ${sec < 10 ? "0" + sec : sec} `
);
// this function is for later use => circular progress bar
setProgress((prevProgress) => {
if (prevProgress == 0) {
return 100;
}
let x = 100 / _totalTime;
return progress - x;
});
};
const convertTotalTime = () => {
let timeToConvert = totalTime;
let min = +Math.floor(timeToConvert / 60 / 1000);
timeToConvert -= Math.floor(timeToConvert / 1000);
setMin((prevState) => prevState + min);
let sec = +Math.floor(timeToConvert / 1000);
timeToConvert -= Math.floor(timeToConvert);
setSec((prevState) => prevState + sec);
};
const startTimerHandler = () => {
convertTotalTime();
setPlayMode(true);
};
return (
<View style={styles.container}>
<Text>{timeString}</Text>
<Button onPress={startTimerHandler} title="Start" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-native-web/0.17.1/index.js"></script>
发布于 2021-07-11 20:17:45
您的导入似乎是错误的...
import React, { useEffect, useState } from "react";
import { Button, StyleSheet, Text, View } from "react-native";干杯,我希望你解决了你的问题!
发布于 2021-07-11 22:12:58
所以这个问题的答案如下
在基于类的组件中,我们通常会重新构造状态、更新值和setIt。
请参阅下面的代码
导出默认函数App() {
useState秒,setSec = const (0);
常量分钟,setMin = useState(0);
..。
const countDown = () => {
// state destructure let [sec, min] = [second, minute];// update sec = sec - 1;// set it againsetSec(sec)// the problem is console.log(second == sec) FALSE // here state wont update for no reason.... // the following is kind of fixsetSec(prevState => prevState -1)// state updates now BUT console.log(second == sec) FALSE !// code below won't ever workif (minute == 0 && second == 0) { // coundown finished console.warn("counter must stop");}}
So here is the only solution I found ...
```javascript```export default function App() {const [second, setSec] = useState(0);const [minute, setMin] = useState(0);...const countDown = () => {let [sec, min] = [second, minute];// keep track of both state and local variable ...sec = sec - 1;setSec((prevState) => prevState - 1);if (sec == 0 && min >= 1) { min = min - 1; setMin((prevState) => prevState - 1);}if (min == 0 && sec == 0) { // coundown finished console.warn("counter must stop");}...};
```https://stackoverflow.com/questions/68335841
复制相似问题