使用react-native-countdown-component时onFinish触发报错求助
问题解决:react-native-countdown-component onFinish回调触发AppState错误
错误原因
你遇到的TypeError: _reactNative.AppState.removeEventListener is not a function错误,是因为react-native-countdown-component旧版本依赖了React Native已废弃的AppState.removeEventListener API。新版RN中该方法已被移除,改为通过订阅对象的remove()方法清理监听。
解决方案
方案1:升级组件版本
检查react-native-countdown-component的版本,执行以下命令升级到适配当前RN版本的最新版:
npm update react-native-countdown-component # 或使用yarn yarn upgrade react-native-countdown-component
方案2:手动修复组件源码(临时方案)
如果暂时无法升级,可直接修改组件内部代码:
- 找到项目中
node_modules/react-native-countdown-component/src/CountDown.js文件 - 修改
componentDidMount中的AppState监听代码:// 原代码 // AppState.addEventListener('change', this.handleAppStateChange); // 修改为 this.appStateSubscription = AppState.addEventListener('change', this.handleAppStateChange); - 修改
componentWillUnmount中的清理代码:// 原代码 // AppState.removeEventListener('change', this.handleAppStateChange); // 修改为 if (this.appStateSubscription) { this.appStateSubscription.remove(); }
方案3:自定义倒计时组件(彻底避免依赖问题)
如果不想依赖第三方组件,可自行用函数式组件实现倒计时:
import { useEffect, useState } from 'react'; import { Text, View, StyleSheet } from 'react-native'; const CustomCountdown = ({ until, onFinish, running }) => { const [remainingTime, setRemainingTime] = useState(until); useEffect(() => { if (!running || remainingTime <= 0) return; const timer = setInterval(() => { setRemainingTime(prev => { if (prev <= 1) { clearInterval(timer); onFinish?.(); return 0; } return prev - 1; }); }, 1000); return () => clearInterval(timer); }, [running, remainingTime, onFinish]); // 格式化剩余时间为DD/HH/MM/SS格式 const formatTime = (totalSeconds) => { const days = Math.floor(totalSeconds / 86400); const hours = Math.floor((totalSeconds % 86400) / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return ( <View style={styles.container}> <Text style={styles.digit}>{days.toString().padStart(2, '0')}</Text> <Text style={styles.label}>DD</Text> <Text style={styles.digit}>{hours.toString().padStart(2, '0')}</Text> <Text style={styles.label}>HH</Text> <Text style={styles.digit}>{minutes.toString().padStart(2, '0')}</Text> <Text style={styles.label}>MM</Text> <Text style={styles.digit}>{seconds.toString().padStart(2, '0')}</Text> <Text style={styles.label}>SS</Text> </View> ); }; return formatTime(remainingTime); }; const styles = StyleSheet.create({ container: { flexDirection: 'row', gap: 4, alignItems: 'center', }, digit: { fontSize: 18, backgroundColor: '#FFF', color: '#1CC625', paddingHorizontal: 6, paddingVertical: 2, borderRadius: 2, }, label: { fontSize: 14, color: '#1CC625', }, }); // 使用示例 // <CustomCountdown // until={exam.staringRemainingTime} // onFinish={() => getExam()} // running={timerIsActive} // />
内容的提问来源于stack exchange,提问作者Sazzad
相关产品推荐
相关产品推荐

