状态未正确更新

问题描述 投票:0回答:1

您好,我刚刚开始使用 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,
  },
});

我什至不知道从哪里开始调试,因为我不明白这个问题。我希望得到一个解释,为什么它的行为不像我预期的那样。

reactjs react-native react-hooks expo state
1个回答
0
投票

更新此行 const [secondsLeft, setSecondsLeft] = useState(22);

© www.soinside.com 2019 - 2024. All rights reserved.