首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React Timer,React Native Timer,

React Timer,React Native Timer,
EN

Stack Overflow用户
提问于 2021-07-11 19:39:21
回答 2查看 57关注 0票数 0

这是React Native中的正常计时器

countDown函数出了点问题,我已经试着找了好几个小时了。

我逐行检查useEffect函数是否正确,convertingTotalTime也工作正常。

一定是setState函数有问题,因为它们不是同步的,但是CountDown函数每秒都会被调用,你可以试试代码片段...

你能帮我理解一下代码有什么问题吗?

代码语言:javascript
复制
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",
  },
});
代码语言:javascript
复制
<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>

EN

回答 2

Stack Overflow用户

发布于 2021-07-11 20:17:45

您的导入似乎是错误的...

代码语言:javascript
复制
import React, { useEffect, useState } from "react";
import { Button, StyleSheet, Text, View } from "react-native";

干杯,我希望你解决了你的问题!

票数 0
EN

Stack Overflow用户

发布于 2021-07-11 22:12:58

所以这个问题的答案如下

在基于类的组件中,我们通常会重新构造状态、更新值和setIt。

请参阅下面的代码

代码语言:javascript
复制

导出默认函数App() {

useState秒,setSec = const (0);

常量分钟,setMin = useState(0);

..。

const countDown = () => {

代码语言:javascript
复制
  //  state destructure
代码语言:javascript
复制
  let [sec, min] = [second, minute];
代码语言:javascript
复制
// update
代码语言:javascript
复制
 sec = sec - 1;
代码语言:javascript
复制
// set it again
代码语言:javascript
复制
setSec(sec)
代码语言:javascript
复制
// the problem is console.log(second == sec)  FALSE 
代码语言:javascript
复制
// here state wont update for no reason.... 
代码语言:javascript
复制
// the following is kind of fix
代码语言:javascript
复制
setSec(prevState => prevState -1)
代码语言:javascript
复制
// state updates now BUT  console.log(second == sec)  FALSE !
代码语言:javascript
复制
// code below won't ever work
代码语言:javascript
复制
if (minute == 0 && second == 0) {
代码语言:javascript
复制
  // coundown finished
代码语言:javascript
复制
  console.warn("counter must stop");
代码语言:javascript
复制
}

}

代码语言:javascript
复制
代码语言:javascript
复制
So here is the only solution I found ...

```javascript
代码语言:javascript
复制
```
代码语言:javascript
复制
export default function App() {
代码语言:javascript
复制
const [second, setSec] = useState(0);
代码语言:javascript
复制
const [minute, setMin] = useState(0);
代码语言:javascript
复制
...
代码语言:javascript
复制
const countDown = () => {
代码语言:javascript
复制
let [sec, min] = [second, minute];
代码语言:javascript
复制
// keep track of both state and local variable ...
代码语言:javascript
复制
sec = sec - 1;
代码语言:javascript
复制
setSec((prevState) => prevState - 1);
代码语言:javascript
复制
if (sec == 0 && min >= 1) {
代码语言:javascript
复制
  min = min - 1;
代码语言:javascript
复制
  setMin((prevState) => prevState - 1);
代码语言:javascript
复制
}
代码语言:javascript
复制
if (min == 0 && sec == 0) {
代码语言:javascript
复制
  // coundown finished
代码语言:javascript
复制
  console.warn("counter must stop");
代码语言:javascript
复制
}
代码语言:javascript
复制
...

};

代码语言:javascript
复制
 ```
代码语言:javascript
复制
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68335841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档