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

求助:React Native中自定义时长参数的倒计时实现示例

React Native 倒计时功能实现示例

完整实现代码

以下是包含UI和倒计时逻辑的完整组件示例,适配你给出的startCountDown函数框架:

import { useState, useEffect, useRef } from 'react';
import { View, TextInput, Picker, Button, Text, StyleSheet } from 'react-native';

export default function CountdownApp() {
  // 输入的计时数值
  const [inputCount, setInputCount] = useState('');
  // 选中的计时单位:sec(秒)/min(分钟)/h(小时)
  const [selectedFormat, setSelectedFormat] = useState('sec');
  // 倒计时运行状态
  const [countdownRunning, setCountdownRunning] = useState(false);
  // 当前剩余总秒数
  const [remainingSeconds, setRemainingSeconds] = useState(0);
  // 定时器引用,用于组件卸载或倒计时结束时清除定时器
  const timerRef = useRef(null);

  // 格式化剩余秒数为可读文本
  const formatTime = (seconds) => {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;

    switch(selectedFormat) {
      case 'h':
        return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
      case 'min':
        return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
      default:
        return `${secs.toString().padStart(2, '0')}秒`;
    }
  };

  // 完善后的倒计时启动函数
  const startCountDown = (countdownObj) => {
    setCountdownRunning(true);
    // 将输入的字符串转为数字
    let totalSeconds = parseInt(countdownObj.count);
    // 根据单位转换为总秒数
    switch(countdownObj.format) {
      case 'min':
        totalSeconds *= 60;
        break;
      case 'h':
        totalSeconds *= 3600;
        break;
      default:
        break;
    }
    setRemainingSeconds(totalSeconds);

    // 启动每秒递减的定时器
    timerRef.current = setInterval(() => {
      setRemainingSeconds(prev => {
        if (prev <= 1) {
          // 倒计时结束,清除定时器并更新状态
          clearInterval(timerRef.current);
          setCountdownRunning(false);
          return 0;
        }
        return prev - 1;
      });
    }, 1000);
  };

  // 组件卸载时清除定时器,防止内存泄漏
  useEffect(() => {
    return () => {
      if (timerRef.current) {
        clearInterval(timerRef.current);
      }
    };
  }, []);

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        keyboardType="numeric"
        value={inputCount}
        onChangeText={setInputCount}
        placeholder="输入计时数值"
        disabled={countdownRunning}
      />
      <Picker
        selectedValue={selectedFormat}
        style={styles.picker}
        onValueChange={(itemValue) => setSelectedFormat(itemValue)}
        enabled={!countdownRunning}
      >
        <Picker.Item label="秒" value="sec" />
        <Picker.Item label="分钟" value="min" />
        <Picker.Item label="小时" value="h" />
      </Picker>
      <Button
        title={countdownRunning ? "倒计时中..." : "开始倒计时"}
        onPress={() => {
          // 仅当未在倒计时且有有效输入时触发
          if (!countdownRunning && inputCount && !isNaN(parseInt(inputCount))) {
            startCountDown({ count: inputCount, format: selectedFormat });
          }
        }}
        disabled={countdownRunning || !inputCount || isNaN(parseInt(inputCount))}
      />
      {/* 显示倒计时文本 */}
      {countdownRunning && (
        <Text style={styles.countdownText}>
          当前剩余:{formatTime(remainingSeconds)}
        </Text>
      )}
    </View>
  );
}

// 基础样式定义
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingHorizontal: 20,
    gap: 16,
  },
  input: {
    height: 44,
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 4,
    paddingHorizontal: 12,
  },
  picker: {
    height: 50,
    width: '100%',
  },
  countdownText: {
    marginTop: 20,
    fontSize: 22,
    textAlign: 'center',
    color: '#e74c3c',
  },
});

关键说明

  • 单位转换逻辑:将输入的数值根据选中的单位转换成总秒数,统一用秒进行倒计时计算,避免不同单位的逻辑混乱。
  • 定时器管理:用useRef保存定时器引用,确保组件卸载或倒计时结束时能正确清除定时器,防止内存泄漏。
  • 输入验证:添加了非空和数字验证,避免无效输入触发倒计时。
  • UI交互限制:倒计时运行时禁用输入框、选择器和开始按钮,防止重复触发。

内容的提问来源于stack exchange,提问作者backenddev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:40:34