我试图用React实现秒表应用程序。一切都已实施,看起来现在正在发挥作用。但是,当我单击停止按钮然后再次启动按钮时,NaN的结果显示在页面上。有什么想法解决这个问题吗?
我认为我应该在某些点将数据类型从String更改为Number。我试图使用Number()来解决问题,但它没有用。
import React from "react";
import { render } from "react-dom";
class Stopwatch extends React.Component {
constructor(props) {
super(props);
this.state = {
startTime: 0,
elapsedTime: 0,
timerId: null,
isRunning: false,
timeToAdd: 0
};
}
updateTimerText = () => {
const m = Math.floor(this.state.elapsedTime / 60000);
const s = Math.floor((this.state.elapsedTime % 60000) / 1000);
this.setState({
elapsedTime: m + ":" + s
});
};
countUp = () => {
this.setState({
timerId: setTimeout(() => {
// this.state.elapsedTime = Date.now() - this.state.startTime;
this.setState({
elapsedTime: Date.now() - this.state.startTime + this.state.timeToAdd
});
this.updateTimerText();
this.countUp();
}, 100)
});
this.state.timerId;
};
handleStart = () => {
if (this.state.isRunning === true) {
return;
}
this.setState({
isRunning: true
});
this.setState({
startTime: Date.now()
});
this.countUp();
};
handleStop = () => {
if (this.state.isRunning === false) {
return;
}
this.setState({
isRunning: false
});
this.setState({
timeToAdd: this.timeToAdd + (Date.now() - this.state.startTime)
});
clearTimeout(this.state.timerId);
};
handleReset = () => {
if (this.state.isRunning === true) {
return;
}
this.setState({
elapsedTime: 0
});
};
render() {
return (
<div>
<div>{this.state.elapsedTime}</div>
<button onClick={this.handleStart}>Start</button>
<button onClick={this.handleStop}>Stop</button>
<button onClick={this.handleReset}>Reset</button>
</div>
);
}
}
render(<Stopwatch />, document.getElementById("root"));
看起来这个问题只是handleStop
中一个被遗忘的小状态访问:
this.setState({
timeToAdd: this.timeToAdd + (Date.now() - this.state.startTime)
});
应该
this.setState({
timeToAdd: this.state.timeToAdd + (Date.now() - this.state.startTime)
});
另一方面,在进行此更改后,重置实际上不会重置秒表,因为timeToAdd保持不变。不确定这是否是预期的行为,但如果不是,那么重置需要
this.setState({
elapsedTime: 0,
timeToAdd: 0,
});
在你的handleStop
方法中你引用this.timeToAdd
,我认为你的意思是this.state.timeToAdd
。尝试将相关行更改为:
timeToAdd: this.state.timeToAdd + (Date.now() - this.state.startTime)
而不是用字符串覆盖elapsedTime
状态键中的数字,我建议添加一个新的密钥...像elapsedTimeFormatted
。您可以将此状态键设置为要在updateTimerText
方法中呈现的字符串,然后在render方法中引用它而不是elapsedTime
。
作为参考,当试图从字符串中获取数字时,您可能需要parseInt
。更多信息请访问MDN
谢谢你照顾我的问题!我无法得到我所期望的原因是我忘了在handleStop
中使用状态访问
并且,另一个发现的错误是在handleReset
。我需要重置timeToAdd。