输入变化重置定时器
Input change resets timer
大家好,我最近开始学习 React,但遇到了一些问题。我正在尝试制作简单的 React 应用程序,我正在制作的组件之一是秒表。
我遇到的问题是,当我开始输入秒表输入时,计时器会重置。
这是我的主要组成部分:
import React, { Component } from 'react';
import Clock from '../components/Clock.jsx';
import Stopwatch from '../components/Stopwatch.jsx';
import '../css/App.css';
import { Form, FormControl, Button } from 'react-bootstrap';
class App extends Component {
constructor(props) {
super(props);
this.state = {
deadline: 'December 25, 2018',
newDeadline: '',
timer: 60,
newTimer: '',
};
}
changeDeadline() {
this.setState({
deadline: this.state.newDeadline,
});
}
changeTimer() {
this.setState({
timer: this.state.newTimer,
});
}
render() {
return (
<div className='app'>
<div className='app_title'>
Countdown to {this.state.deadline}
</div>
<Clock
deadline = {this.state.deadline}
/>
<Form inline >
<FormControl
className="deadline_input"
type="text"
placeholder="New date"
onChange={event => this.setState({newDeadline: event.target.value})}
onKeyPress={event => {
if (event.key === 'Enter') {
event.preventDefault();
this.changeDeadline();
}
}}
/>
<Button onClick={() => this.changeDeadline()} >
Submit
</Button>
</Form>
<div className="stopwatch_title">
Stopwatch from {this.state.timer} seconds
</div>
<Form inline>
<FormControl
className="stopwatch_input"
type="text"
placeholder="Enter time"
onChange={event => this.setState({newTimer: event.target.value})}
onKeyPress={event => {
if (event.key === 'Enter') {
event.preventDefault();
this.changeTimer();
}
}}
/>
<Button onClick={() => this.changeTimer()} >
Submit
</Button>
</Form>
<Stopwatch
timer = {this.state.timer}
/>
</div>
);
}
}
export default App;
和我的秒表组件:
import React, {Component} from 'react';
import '../css/App.css';
import { Button } from 'react-bootstrap';
class Stopwatch extends Component {
constructor(props) {
super(props);
this.state = {
stopwatch: props.timer,
};
this.decrementer = null;
}
componentWillReceiveProps(nextProps) {
clearInterval(this.decrementer);
this.timerCountdown(nextProps.timer);
}
timerCountdown(newTimer) {
// First we update our stopwatch with new timer
this.setState({
stopwatch: newTimer
});
}
startTimer() {
// Then we decrement stopwatch by 1 every second
this.decrementer = setInterval( () => {
this.setState({
stopwatch: this.state.stopwatch -1,
});
},1000);
}
componentDidUpdate() {
if (this.state.stopwatch < 1) {
clearInterval(this.decrementer);
alert('Countdown finished');
}
}
render() {
return(
<div>
<Button onClick={() => this.startTimer()} >
Start
</Button>
<div className="stopwatch"> {this.state.stopwatch} </div>
</div>
);
}
}
export default Stopwatch;
这是问题的 gif https://imgur.com/9xqMW96
如您所见,在我开始输入内容后我的计时器会重置。我希望它仅在用户按下 enter
键或使用 submit
按钮时重置。
我试过这样做:
<input value={this.state.newTimer} onChange={evt => this.updateInputValue(evt)}/>
updateInputValue: function(evt) {
this.setState({
newTimer: evt.target.value
});
}
但它对我不起作用。
您可以在此处查看实际代码:https://karadjordje.github.io/countdown-stopwatch-react/
您正在停止 interval
组件收到的每个新道具。
您可以在本地 state
中处理时间,也可以显式地从父级传递正确的新值。
我做了一个小的基本示例,因此您可以看到数据流以及每个事件如何负责一小部分数据。
希望对您有所帮助。
class App extends React.Component {
state = {
startTime: 5,
currentTime: 5,
textInput: ''
}
startTimer = () => {
if (this.interval) {
clearInterval(this.interval);
}
this.interval = setInterval(() => {
this.setState(prev => {
if (prev.currentTime === 0) {
this.stopTimer();
return { ...prev, currentTime: prev.startTime };
} else {
return {
...prev,
currentTime: prev.currentTime - 1
}
}
})
}, 1000)
}
stopTimer = () => {
clearInterval(this.interval);
}
updateInput = ({ target }) => {
this.setState(prev => ({ textInput: target.value }));
}
setStartTime = () => {
this.stopTimer();
this.setState(({ textInput }) => ({ startTime: textInput, currentTime: textInput, textInput: '' }));
}
render() {
const { currentTime, textInput } = this.state;
return (
<div >
<div>{currentTime}</div>
<button onClick={this.startTimer}>Start timer</button>
<div>
<input placeholder="Enter start time" value={textInput} onChange={this.updateInput} />
<button onClick={this.setStartTime}>Set Start time</button>
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我更新了我的代码。
我没有使用 componentWillUpdate
,而是使用 componentDidUpdate
,这是我的代码:
componentDidUpdate(prevProps) {
console.log('componentDidUpdate', this.props, prevProps);
if (prevProps.timer !== this.props.timer) {
this.updateTimer(this.props.timer);
clearInterval(this.decrementer);
}
if (this.state.stopwatch < 1) {
clearInterval(this.decrementer);
alert('Countdown finished');
}
}
基本上我只是在更新计时器,因为之前的计时器与当前的不同。
大家好,我最近开始学习 React,但遇到了一些问题。我正在尝试制作简单的 React 应用程序,我正在制作的组件之一是秒表。
我遇到的问题是,当我开始输入秒表输入时,计时器会重置。
这是我的主要组成部分:
import React, { Component } from 'react';
import Clock from '../components/Clock.jsx';
import Stopwatch from '../components/Stopwatch.jsx';
import '../css/App.css';
import { Form, FormControl, Button } from 'react-bootstrap';
class App extends Component {
constructor(props) {
super(props);
this.state = {
deadline: 'December 25, 2018',
newDeadline: '',
timer: 60,
newTimer: '',
};
}
changeDeadline() {
this.setState({
deadline: this.state.newDeadline,
});
}
changeTimer() {
this.setState({
timer: this.state.newTimer,
});
}
render() {
return (
<div className='app'>
<div className='app_title'>
Countdown to {this.state.deadline}
</div>
<Clock
deadline = {this.state.deadline}
/>
<Form inline >
<FormControl
className="deadline_input"
type="text"
placeholder="New date"
onChange={event => this.setState({newDeadline: event.target.value})}
onKeyPress={event => {
if (event.key === 'Enter') {
event.preventDefault();
this.changeDeadline();
}
}}
/>
<Button onClick={() => this.changeDeadline()} >
Submit
</Button>
</Form>
<div className="stopwatch_title">
Stopwatch from {this.state.timer} seconds
</div>
<Form inline>
<FormControl
className="stopwatch_input"
type="text"
placeholder="Enter time"
onChange={event => this.setState({newTimer: event.target.value})}
onKeyPress={event => {
if (event.key === 'Enter') {
event.preventDefault();
this.changeTimer();
}
}}
/>
<Button onClick={() => this.changeTimer()} >
Submit
</Button>
</Form>
<Stopwatch
timer = {this.state.timer}
/>
</div>
);
}
}
export default App;
和我的秒表组件:
import React, {Component} from 'react';
import '../css/App.css';
import { Button } from 'react-bootstrap';
class Stopwatch extends Component {
constructor(props) {
super(props);
this.state = {
stopwatch: props.timer,
};
this.decrementer = null;
}
componentWillReceiveProps(nextProps) {
clearInterval(this.decrementer);
this.timerCountdown(nextProps.timer);
}
timerCountdown(newTimer) {
// First we update our stopwatch with new timer
this.setState({
stopwatch: newTimer
});
}
startTimer() {
// Then we decrement stopwatch by 1 every second
this.decrementer = setInterval( () => {
this.setState({
stopwatch: this.state.stopwatch -1,
});
},1000);
}
componentDidUpdate() {
if (this.state.stopwatch < 1) {
clearInterval(this.decrementer);
alert('Countdown finished');
}
}
render() {
return(
<div>
<Button onClick={() => this.startTimer()} >
Start
</Button>
<div className="stopwatch"> {this.state.stopwatch} </div>
</div>
);
}
}
export default Stopwatch;
这是问题的 gif https://imgur.com/9xqMW96
如您所见,在我开始输入内容后我的计时器会重置。我希望它仅在用户按下 enter
键或使用 submit
按钮时重置。
我试过这样做:
<input value={this.state.newTimer} onChange={evt => this.updateInputValue(evt)}/>
updateInputValue: function(evt) {
this.setState({
newTimer: evt.target.value
});
}
但它对我不起作用。 您可以在此处查看实际代码:https://karadjordje.github.io/countdown-stopwatch-react/
您正在停止 interval
组件收到的每个新道具。
您可以在本地 state
中处理时间,也可以显式地从父级传递正确的新值。
我做了一个小的基本示例,因此您可以看到数据流以及每个事件如何负责一小部分数据。
希望对您有所帮助。
class App extends React.Component {
state = {
startTime: 5,
currentTime: 5,
textInput: ''
}
startTimer = () => {
if (this.interval) {
clearInterval(this.interval);
}
this.interval = setInterval(() => {
this.setState(prev => {
if (prev.currentTime === 0) {
this.stopTimer();
return { ...prev, currentTime: prev.startTime };
} else {
return {
...prev,
currentTime: prev.currentTime - 1
}
}
})
}, 1000)
}
stopTimer = () => {
clearInterval(this.interval);
}
updateInput = ({ target }) => {
this.setState(prev => ({ textInput: target.value }));
}
setStartTime = () => {
this.stopTimer();
this.setState(({ textInput }) => ({ startTime: textInput, currentTime: textInput, textInput: '' }));
}
render() {
const { currentTime, textInput } = this.state;
return (
<div >
<div>{currentTime}</div>
<button onClick={this.startTimer}>Start timer</button>
<div>
<input placeholder="Enter start time" value={textInput} onChange={this.updateInput} />
<button onClick={this.setStartTime}>Set Start time</button>
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我更新了我的代码。
我没有使用 componentWillUpdate
,而是使用 componentDidUpdate
,这是我的代码:
componentDidUpdate(prevProps) {
console.log('componentDidUpdate', this.props, prevProps);
if (prevProps.timer !== this.props.timer) {
this.updateTimer(this.props.timer);
clearInterval(this.decrementer);
}
if (this.state.stopwatch < 1) {
clearInterval(this.decrementer);
alert('Countdown finished');
}
}
基本上我只是在更新计时器,因为之前的计时器与当前的不同。