I am trying to create a clock, where the user can select a location and the current time there is rendered on the screen. The code works fine for the first user button click. However, if they then select a different location, the hour state value should update to the new value. It does this, but react is rendering the old value to the screen too. The hour on the clock, therefore, flickers between the two different values. Can anyone explain why this is happening, and how I can only display the new hour value after the user clicks for a second time?
import React from 'react';
import ReactDOM from 'react-dom';
import ButtonClick from './Components/UserInputs.js'
//define global time difference matrix
var timeDiffMat= [0, 6, 1, 2, -5];
class Clock extends React.Component {
constructor(props) {
super(props);
//this.userInput = this.userInput.bind(this);
this.adjustForLocation = this.adjustForLocation.bind(this);
this.tick = this.tick.bind(this);
this.state = {CityfromChild: "", hours:0, minutes: 0, seconds: 0,
test:''};
//this.initialSetTime = this.initialSetTime.bind(this);
this.setTime = this.setTime.bind(this);
}
adjustForLocation(citySelected, numberOfClicks) {
function getTimeDiff () {
if (citySelected == "Local Time") return timeDiffMat[0]
if (citySelected =="Tokyo") return timeDiffMat[1]
if (citySelected =="Cape Town") return timeDiffMat[2]
if (citySelected =="Moscow")return timeDiffMat[3]
if (citySelected =="New York") return timeDiffMat[4]
}
this.timeDiff = getTimeDiff(citySelected)
this.tick(this.timeDiff)
}
tick(timeDiff){
setInterval(()=> this.setTime(timeDiff), 1000)
}
setTime(timeDiff){
this.setState({
seconds: new Date().getSeconds(),
minutes: new Date().getMinutes()
});
this.setState({hours: timeDiff + new Date().getHours() })
}
// unmount Clock Component and invalidate timer
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div className="border">
<h3> Choose a city {}</h3>
<div className="button-container">
<ul>
<li> <ButtonClick getTimeOnClick =
{this.userInput} adjustHoursForCity = {this.adjustForLocation}
buttonLabel= "Local Time"/> </li>
<li> <ButtonClick getTimeOnClick =
{this.userInput} adjustHoursForCity = {this.adjustForLocation}
buttonLabel= "Cape Town"/> </li>
<li> <ButtonClick getTimeOnClick =
{this.userInput} adjustHoursForCity = {this.adjustForLocation}
buttonLabel= "Moscow"/> </li>
<li> <ButtonClick getTimeOnClick =
{this.userInput} adjustHoursForCity = {this.adjustForLocation}
buttonLabel= "New York"/> </li>
<li> <ButtonClick getTimeOnClick =
{this.userInput} adjustHoursForCity = {this.adjustForLocation}
buttonLabel= "Tokyo"/> </li>
<button>{this.state.CityfromChild}</button>
<button>{this.state.test}</button>
</ul>
</div>
<div>{this.state.hours}:{this.state.minutes}:
{this.state.seconds} </div>
</div>
);
}
}
When you update the time you create a new setInterval
, but you don't clear the old one. So you will have multiple setInterval
each setting the time using a different timeDiff
.
Try something like:
tick(timeDiff) {
if (this.timer) {
clearInterval(this.timer);
}
this.timer = setInterval(() => this.setTime(timeDiff), 1000)
}