我已经创建了一个计时器模块,其中有一个输入和三个按钮1-Start(启动计时器)2-Pause(暂停计时器)3-Stop(停止计时器),现在问题是当我输入任何值并启动计时器时,当我按下“停止”按钮时,该值变为0但是当我再次点击时 “开始”按钮计数器从我在停止按钮时单击的前一个值开始,而不是它应该从之前写入输入字段的值开始。如果你不理解我所说的话,请检查一下。
代码:
<!Doctype html>
<html>
<head>
<title>React 1</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
<script src="https://unpkg.com/react-form-with-constraints/dist/react-form-with-constraints.js"></script>
</head>
<body>
<script type="text/jsx">
var styles = {
margin: '2em auto',
width: '300px',
height: '300px',
backgroundColor: '#DD4814',
color: '#ffffff',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'space-around'
};
var inputs = {
position: 'relative',
bottom: '17%',
left: '20%'
}
var btns = {
position: 'relative',
bottom: '7%'
}
var btn = {
backgroundColor: '#ffffff',
color: '#000000',
borderColor: '#DEB887',
borderRadius: '0.4em',
cursor: 'pointer',
margin: '0 1em',
padding: '0.5em',
display: 'inline-block'
}
class Timer extends React.Component {
constructor (props) {
super(props)
this.state =
{
count: 0,
customNumber: 0
}
}
handleChange (e) {
this.setState({ customNumber: e.target.value});
}
componentWillUnmount () {
clearInterval(this.timer)
}
tick () {
if (this.state.customNumber) {
this.setState({
count: (this.state.customNumber--)
})
if (this.state.customNumber <= 0) {
this.setState({ count: 0})
clearInterval(this.timer)
this.setState({ disabled: false })
}
} else {
this.setState({count: (this.state.count - 1)})
}
}
display () {
return ('0' + this.state.count % 100).slice(-2)
}
startTimer () {
if (this.state.customNumber == "" || isNaN(this.state.customNumber))
{
alert("Please give some value in number");
} else {
clearInterval(this.timer)
this.timer = setInterval(this.tick.bind(this), 1000)
this.setState({ disabled: true })
}
}
stopTimer () {
clearInterval(this.timer)
}
resetTimer () {
clearInterval(this.timer)
this.setState({count: 0})
this.setState({ disabled: false })
}
render () {
return (
<div style={styles} className='timer'>
<h1 style={{fontSize: '4em'}}>{this.display()}</h1>
<div className="input_text" style={inputs}>
<label htmlFor="custom_number">Enter number to start timer</label>
<input type="text" name="custom_number" id="custom_number" value={this.state.inputValue} onChange={this.handleChange.bind(this)} disabled={this.state.disabled} placeholder="Enter b/w 1-100" />
</div>
<div style={btns} className="buttons">
<button style={btn} type="button" name="start_btn" id="start_btn" onClick={this.startTimer.bind(this)}>Start</button>
<button style={btn} type="button" name="stop_btn" id="stop_btn" onClick={this.stopTimer.bind(this)}>Pause</button>
<button style={btn} type="button" name="reset_btn" id="reset_btn" onClick={this.resetTimer.bind(this)}>Stop</button>
</div>
</div>
)
}
}
ReactDOM.render( <Timer />, document.getElementById('root') )
</script>
<div id="root"></div>
</body>
</html>
答案 0 :(得分:0)
您的所有代码都很好,但您需要进行一些更改才能使其按预期正常工作。
首先,您需要保存倒计时的最后一个输入(数字),所以让我们将lastInput: 0
添加到组件的状态,当您在输入字段中输入某个数字时,该状态将被填充,因此每个键入lastInput
属性的时间将随您设置的值而变化。
点击“停止”按钮后,您只执行此操作:this.setState({ count: 0 })
但是您忘记了其他内容,还需要重新启动属性customNumber
才能重置,所以您需要这样做this:this.setState({ count: 0, customNumber: this.state.lastInput })
其中this.state.lastInput
具有用户设置的最后一个值,即为了避免将输入的值保存到局部变量中,所以我认为最好将该值保存到组件状态中。
注意强>
如果你在你的React组件中使用babel,那么使用ES6中的箭头功能会更好,所以你可以避免使用this.myfunction.bind(this)
语法,这样你就可以这样做:
以你的代码为例,就像这样:
handleChange = (e) => {
var value = e.target.value;
this.setState({ customNumber: value, lastInput: value });
}
现在你可以使用上面的函数而不用bind
<input className="some-classname" onChange={this.handleChange} />
上面发生了什么?,所以ES6中的箭头函数会为你做绑定过程,这是神奇的自动,当外部元素调用你的函数时,它会避免你的函数松开它们的范围。
<强>记住强>
只有当您使用babel将ES6代码转换为ES5以使旧浏览器可以理解时,才能执行上述代码。
<!Doctype html>
<html>
<head>
<title>React 1</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
<script src="https://unpkg.com/react-form-with-constraints/dist/react-form-with-constraints.js"></script>
</head>
<body>
<script type="text/jsx">
var styles = {
margin: '2em auto',
width: '300px',
height: '300px',
backgroundColor: '#DD4814',
color: '#ffffff',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'space-around'
};
var inputs = {
position: 'relative',
bottom: '17%',
left: '20%'
}
var btns = {
position: 'relative',
bottom: '7%'
}
var btn = {
backgroundColor: '#ffffff',
color: '#000000',
borderColor: '#DEB887',
borderRadius: '0.4em',
cursor: 'pointer',
margin: '0 1em',
padding: '0.5em',
display: 'inline-block'
}
class Timer extends React.Component {
constructor (props) {
super(props)
this.state =
{
count: 0,
customNumber: 0,
lastInput: 0
}
}
handleChange (e) {
const value = e.target.value;
this.setState({ customNumber: value, lastInput: value});
}
componentWillUnmount () {
clearInterval(this.timer)
}
tick () {
if (this.state.customNumber) {
this.setState({
count: (this.state.customNumber--)
})
if (this.state.customNumber <= 0) {
this.setState({ count: 0})
clearInterval(this.timer)
this.setState({ disabled: false })
}
} else {
this.setState({count: (this.state.count - 1)})
}
}
display () {
return ('0' + this.state.count % 100).slice(-2)
}
startTimer () {
if (this.state.customNumber == "" || isNaN(this.state.customNumber))
{
alert("Please give some value in number");
} else {
clearInterval(this.timer)
this.timer = setInterval(this.tick.bind(this), 1000)
this.setState({ disabled: true })
}
}
stopTimer () {
clearInterval(this.timer)
}
resetTimer () {
clearInterval(this.timer)
this.setState({count: 0, customNumber: this.state.lastInput})
this.setState({ disabled: false })
}
render () {
return (
<div style={styles} className='timer'>
<h1 style={{fontSize: '4em'}}>{this.display()}</h1>
<div className="input_text" style={inputs}>
<label htmlFor="custom_number">Enter number to start timer</label>
<input type="text" name="custom_number" id="custom_number" value={this.state.inputValue} onChange={this.handleChange.bind(this)} disabled={this.state.disabled} placeholder="Enter b/w 1-100" />
</div>
<div style={btns} className="buttons">
<button style={btn} type="button" name="start_btn" id="start_btn" onClick={this.startTimer.bind(this)}>Start</button>
<button style={btn} type="button" name="stop_btn" id="stop_btn" onClick={this.stopTimer.bind(this)}>Pause</button>
<button style={btn} type="button" name="reset_btn" id="reset_btn" onClick={this.resetTimer.bind(this)}>Stop</button>
</div>
</div>
)
}
}
ReactDOM.render( <Timer />, document.getElementById('root') )
</script>
<div id="root"></div>
</body>
</html>