You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native倒计时计时器启停失效,请求代码排查

React Native倒计时启停问题排查与修复

核心问题点

  • 按钮逻辑与事件绑定错误
    • Timer组件中按钮的显示文本搞反了:isStarted为true时应该显示“暂停”,为false时显示“开始”
    • 暂停按钮的onPress事件错误嵌套了console.log,导致状态更新函数被包裹在日志输出里,无法正确触发状态变更
  • Countdown组件定时器清理不完整
    • 倒计时归0后没有主动清理定时器,会导致无效的定时任务持续运行
    • useEffect依赖数组缺少countDown函数,不符合hooks依赖规范(虽不影响功能,但存在隐患)

修复后的完整代码

Countdown组件修复

const minutesToMill = (min) => min * 1000 * 60;
const formatTime = (time) => (time < 10 ? `0${time}` : time);

export const Countdown = ({ 
  minutes = 20,
  isPaused,
}) => {
  const interval = React.useRef(null);
  const [millis, setMillis] = useState(minutesToMill(minutes));

  const countDown = () => {
    setMillis((time) => {
      if (time === 0) {
        // 时间归0时主动清理定时器
        clearInterval(interval.current);
        return time;
      }
      const timeLeft = time - 1000;
      return timeLeft;
    });
  };

  const minute = Math.floor(millis / 1000 / 60) % 60;
  const second = Math.floor(millis / 1000) % 60;

  useEffect(() => {
    if (isPaused) {
      return;
    }
    // 启动新定时器前清理旧的,避免多个定时器同时运行
    if (interval.current) clearInterval(interval.current);
    interval.current = setInterval(countDown, 1000);

    return () => clearInterval(interval.current);
  }, [isPaused, countDown]);

  return (
    <Text style={styles.text}>
      {formatTime(minute)} : {formatTime(second)}
    </Text>
  );
};

Timer组件修复

export const Timer = ({focusSubject}) => {
  const [isStarted, setIsStarted] = useState(false);

  return (
    <View style={styles.container}>
      <View style={styles.countdown}>
        <Countdown isPaused={!isStarted} />
      </View>
      
      <View style={{paddingTop: spacing.xxl}}>
        <Text style={styles.title}>Focusing on </Text>
        <Text style={styles.task}>{focusSubject} </Text> 
      </View>
      
      <View style={styles.buttonWrapper}>
        {isStarted ? (
          <RoundedButton title="pause" onPress={() => setIsStarted(false)} />
        ) : (
          <RoundedButton title="start" onPress={() => setIsStarted(true)} />
        )}
      </View>
    </View>
  );
};

修复说明

  1. 修正Timer组件按钮的文本显示逻辑,让按钮功能与文本匹配
  2. 移除onPress事件中多余的console.log,确保状态更新函数直接执行
  3. 在Countdown组件的倒计时函数中,添加时间归0时的定时器清理逻辑
  4. 给useEffect补充countDown依赖,并在启动新定时器前清理旧实例,避免定时器叠加
  5. 保留状态的函数式更新写法,确保状态更新的准确性

内容的提问来源于stack exchange,提问作者Aderoba Dayo Jerry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:05:42