React Native倒计时计时器实现问题:setTimeout调用后报错
解决React倒计时函数中
this.state未定义的问题 嘿,这个问题我太熟了!你遇到的undefined is not an object(evaluating this.state.text)错误,核心原因是**setTimeout回调里的this指向丢失**了——当你直接把this.clock传给setTimeout时,回调执行时的this不再指向你的组件实例,自然就找不到this.state了。下面给你几个靠谱的解决办法:
方法1:用箭头函数包裹回调
箭头函数会继承外层作用域的this,所以这样写能确保回调里的this指向组件实例:
clock() { let presentTime = this.state.text; var timeArray = presentTime.split(/[:]+/); var m = parseInt(timeArray[0], 10); // 记得转成数字,避免字符串减法出问题 var s = this.checkSecond(parseInt(timeArray[1], 10) - 1); if (s === 59) { m -= 1; } // 边界处理:倒计时结束就停止 if (m < 0) { return; } this.setState({ text: `${m.toString().padStart(2, '0')}:${s}` }); // 用箭头函数包裹this.clock setTimeout(() => this.clock(), 1000); }
方法2:在构造函数中绑定this
提前把clock方法的this绑定到组件实例,这样后续调用时this就不会变了:
constructor(props) { super(props); this.state = { text: "45:59" }; // 关键:绑定this this.clock = this.clock.bind(this); this.checkSecond = this.checkSecond.bind(this); } clock() { // ...你的原有逻辑 setTimeout(this.clock, 1000); // 现在可以直接传this.clock了 }
方法3:把clock定义成箭头函数类方法
箭头函数类方法会自动绑定组件实例的this,写法更简洁:
// 注意这里用箭头函数定义方法 clock = () => { let presentTime = this.state.text; var timeArray = presentTime.split(/[:]+/); var m = parseInt(timeArray[0], 10); var s = this.checkSecond(parseInt(timeArray[1], 10) - 1); if (s === 59) { m -= 1; } if (m < 0) { return; } this.setState({ text: `${m.toString().padStart(2, '0')}:${s}` }); setTimeout(this.clock, 1000); }
另外补充两个细节:
- 你的
checkSecond函数似乎没写完,给你补个完整的版本,保证秒数是两位数:
checkSecond(sec) { if (sec < 0) return 59; return sec.toString().padStart(2, '0'); // 比如把9变成09 }
- 记得处理内存泄漏:保存
setTimeout的返回值,在组件卸载时清除定时器:
componentDidMount() { this.timerId = setTimeout(this.clock, 1000); } componentWillUnmount() { clearTimeout(this.timerId); }
这样修改后,你的倒计时应该就能正常跑起来啦!
内容的提问来源于stack exchange,提问作者john
相关产品推荐
相关产品推荐

