我目前正在使用React开发一个简单的秒表应用程序,并且在单击“开始”按钮时更新“ secondsPassed”道具时遇到一些问题。我目前收到错误消息:
TypeError:无法设置未定义的属性“计数器”
在handleStart事件中发生错误。我将thisStart定义为具有handleStart事件的范围。我相信我在构造函数中定义了变量计数器,并且尝试通过将传递的秒数增加1来更新该计数器。
import React, { Component } from 'react';
import '../assests/stopwatch.css';
class StopWatch extends Component {
// handle state
constructor(props) {
super(props);
this.state = {
secondsPassed: 0,
counter: 0
};
}
// define event functions for start, pause and reset
handleStart() {
let thisStart = this;
this.counter = setInterval(() => {
thisStart.setState({
secondsPassed: (thisStart.state.secondsPassed + 1)
});
}, 1000)
}
handlePause() {
clearInterval(this.counter);
}
handleReset() {
this.getInitialState()
}
// define function that shows the seconds passed
// the initial state is going to be zero
getInitialState() {
return { secondsPassed: 0 };
}
getSeconds() {
return ('0' + this.state.secondsPassed % 60).slice(-2);
}
getMinutes() {
return Math.floor(this.state.secondsPassed / 60);
}
render() {
return (
<React.Fragment>
<div id="container">
<h1>Stopwatch APP</h1>
<div id="stopwatch-container">
<div className="time-container">
<span>{this.getMinutes()}:{this.getSeconds()}</span>
</div>
<div className="button-container">
<div className="start-button">
<button type="button" onClick={this.handleStart}>Start</button>
</div>
<div className="pause-button">
<button type="button" onClick={this.handlePause}>Pause</button>
</div>
<div className="reset-button">
<button type="button" onClick={this.handleReset}>Reset</button>
</div>
</div>
</div>
</div>
</React.Fragment >
);
}
}
export default StopWatch;
答案 0 :(得分:1)
¿计数器是变量还是函数?他正在寻找一个名为 counter 的全局属性。 分配状态的正确方法是:
this.setState( obj );
其中 obj 是您的对象。我不明白为什么您要使用'this.state.secondsPassed',但是使用计数器'this.counter'时它应该是相同的。
阅读这两篇关于React States和Lifecycle(还包含计时器功能)的文章,以便您首先可以阐明当前的理解。
编辑: 也许您正在尝试使用counter和secondsPassed重用它们的值,在这种情况下,您可以使用发送给setState的参数:
this.setState( (previousState) => {
previousState.counter = 0;
return previousState;
}
在这里,我们只是将先前的 secondsPassed 值与 counter 的新值一起使用。
答案 1 :(得分:1)
您应该绑定回调。 要么在JSX中使用
<button ... onClick={this.handleStart.bind(this)}...>
或在构造函数中
constructor () {
super(props);
this.handleStart = this.handleStart.bind(this);
// do this for the rest of the functions
}
您无需为interval函数创建自定义范围,简单的箭头函数即可解决问题。
答案 2 :(得分:1)
我假设您在handleStart中定义了this.counter,因为您想将其用作clearInterval的ID,但是我认为您应该使用this.state.counter而不是this.counter,并且您没有在构造函数中绑定该函数,这会导致一些问题。
constructor(props) {
super(props);
this.handleStart = this.handleStart.bind(this)
this.handlePause = this.handlePause.bind(this)
this.getInitialState = this.getInitialState.bind(this)
this.handleReset = this.handleReset.bind(this)
this.state = {
secondsPassed: 0,
counter: 0
};
}
...
handleStart() {
this.state.counter = setInterval(() => {
this.setState({
secondsPassed: this.state.secondsPassed + 1
})
},1000)
}
handlePause() {
clearInterval(this.state.counter);
}
顺便说一句,我认为getInitialState中的返回没有意义,应该使用setState
getInitialState() {
// return { secondsPassed: 0 };
this.setState({
secondsPassed: 0
})
}