【问题标题】:Start Stop button not working in sync in react开始停止按钮在反应中不同步工作
【发布时间】:2017-09-26 03:44:15
【问题描述】:

我从 react 创建了一个计时器模块,其中有一个输入和三个按钮 1-开始(启动计时器) 2-暂停(暂停计时器) 3-停止(停止计时器),现在问题是当我输入任何值并启动计时器时,当我按下“停止”按钮时,值变为 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>

【问题讨论】:

  • 我看不到 onChange={this.handleChange.bind(this)} 的定义。这可能是问题所在。您的状态 --> customCount 没有来自输入的值。
  • 我已经定义好了

标签: javascript reactjs timer


【解决方案1】:

您的所有代码几乎都没有问题,但您需要进行一些更改以使其按预期正常工作。

首先,您需要保存最后一个输入(数字)以进行倒计时,所以让我们将lastInput: 0 添加到组件的状态中,当您在输入字段中输入一些数字时,该状态将被填充,所以每次您键入lastInput 属性将随您设置的值而变化。

点击停止按钮后,您只需要这样做:this.setState({ count: 0 }),但您忘记了其他内容,您还需要重新启动属性customNumber 才能重置它,因此您需要这样做:@987654325 @ 其中this.state.lastInput 是用户设置的最后一个值,这是为了避免将输入的值保存到局部变量中,所以我认为最好将该值保存到组件状态中。

注意

如果你在 React 组件中使用 babel,最好使用 ES6 中的箭头函数,这样你就可以避免 this.myfunction.bind(this) 语法,这样你就可以这样做:

以你的代码为例,它会是这样的:

handleChange = (e) => {
  var value = e.target.value;
  this.setState({ customNumber: value, lastInput: value });
}

现在你可以不用绑定就可以使用上面的函数了

<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>

【讨论】:

  • 您的代码不起作用,现在“停止”按钮也不起作用
  • 当我点击“停止”按钮时,该值应在上方显示 0,但在点击“开始”按钮后,计数器再次从给定的输入值开始。
  • 非常感谢它工作正常,请详细说明您做了什么?
  • @naveendharni 哦,是的,我当然会详细说明我的答案来解释我做了什么
猜你喜欢
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 2015-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多