ReactJs倒计时意外重置求助:仅需在计时结束时重启
这个问题我之前用react-countdown-now时也碰到过!核心原因很简单:每次你在输入框里打字,组件都会重新渲染,而你给Countdown的date属性每次都在重新计算Date.now() + 120000——相当于每次都给了它一个全新的结束时间,所以倒计时自然会跟着重启。
要解决这个问题,你需要把倒计时的结束时间存在组件的state里,让它只在你真正想要重启的时候(也就是倒计时结束时)才更新。下面是调整后的完整代码:
import React from 'react'; import { Input } from 'reactstrap'; import Countdown from 'react-countdown-now'; import { connect } from 'react-redux'; class Foo extends React.Component { constructor(props) { super(props); this.state = { code: '', disabled: false, countdownEndDate: Date.now() + 120000, // 初始化倒计时结束时间 }; this.update = this.update.bind(this); this.resetCountdown = this.resetCountdown.bind(this); } update(e) { this.setState({ code: e.target.value }); } resetCountdown() { // 仅在倒计时结束时重置结束时间 this.setState({ countdownEndDate: Date.now() + 120000 }); } render() { // 将renderer移到组件内部,方便调用重置方法 const renderer = ({ minutes, seconds, completed }) => { if (completed) { this.resetCountdown(); return <p>reset</p>; } // 给秒数补零,优化显示体验 const formattedSeconds = seconds.toString().padStart(2, '0'); return ( <p> {minutes}:{formattedSeconds} </p> ); }; return ( <div> <Input className="text-center activationCode__letter-spacing" maxLength="4" type="text" pattern="\d*" id="activationCode__input-fourth" bsSize="lg" value={this.state.code} onChange={this.update} /> <Countdown date={this.state.countdownEndDate} renderer={renderer} /> </div> ); } } const mapStateToProps = state => ({ user: state.auth, }); export default connect( mapStateToProps, null, )(Foo);
关键改动说明:
- 把结束时间存入state:在constructor里初始化
countdownEndDate,输入框内容变化时这个值不会改变,Countdown也就不会无故重启。 - 新增重置方法:
resetCountdown专门用来更新倒计时结束时间,只在倒计时完成时调用。 - 将renderer移到组件内部:这样可以直接访问组件的
resetCountdown方法,确保只有倒计时结束时才触发重置。 - 额外优化:给秒数补零,避免出现
1:5这种不美观的显示,改成1:05更符合用户习惯。
内容的提问来源于stack exchange,提问作者Farzan Najipour
相关产品推荐
相关产品推荐

