求助: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
相关产品推荐
相关产品推荐

