react render 正在使用旧的和新的状态值,而不仅仅是新值
react render is using old and new state values, instead of just the new value
我正在尝试创建一个时钟,用户可以在其中 select 位置和当前时间呈现在屏幕上。该代码适用于第一次用户按钮点击。但是,如果他们然后 select 一个不同的位置,小时状态值应该更新为新值。它会这样做,但 React 也会将旧值渲染到屏幕上。因此,时钟上的小时在两个不同的值之间闪烁。谁能解释为什么会这样,以及我如何只能在用户第二次点击后显示新的小时值?
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>
);
}
}
当您更新时间时,您会创建一个新的 setInterval
,但不会清除旧的。因此,您将有多个 setInterval
,每个设置时间使用不同的 timeDiff
。
试试这样的东西:
tick(timeDiff) {
if (this.timer) {
clearInterval(this.timer);
}
this.timer = setInterval(() => this.setTime(timeDiff), 1000)
}
您应该将 setTimeInterval
绑定到您的组件,例如 this.mySetTimeInterval = setTimeInterval(() => {});
在其他任何地方,您都可以停止 运行 间隔:
clearInterval(this.mySetTimeInterval)
您的代码中没有 this.interval
,就像在 componentWillUnmount
中使用的那样,在函数 tick
中,我相信您想将 setInterval 调用的结果存储在一个变量中命名区间。正如@rebecca 所说,您可能应该使用
setTime(timeDiff) {
setState(/* To avoid race conditions */ function(){
return {
seconds: new Date().getSeconds(),
minutes: new Date().getMinutes(),
hours: timeDiff + new Date().getHours()
})
}
tick(timeDiff) {
this.interval = setInterval(() => this.setTime(timeDiff), 1000)
}
避免竞争条件
我正在尝试创建一个时钟,用户可以在其中 select 位置和当前时间呈现在屏幕上。该代码适用于第一次用户按钮点击。但是,如果他们然后 select 一个不同的位置,小时状态值应该更新为新值。它会这样做,但 React 也会将旧值渲染到屏幕上。因此,时钟上的小时在两个不同的值之间闪烁。谁能解释为什么会这样,以及我如何只能在用户第二次点击后显示新的小时值?
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>
);
}
}
当您更新时间时,您会创建一个新的 setInterval
,但不会清除旧的。因此,您将有多个 setInterval
,每个设置时间使用不同的 timeDiff
。
试试这样的东西:
tick(timeDiff) {
if (this.timer) {
clearInterval(this.timer);
}
this.timer = setInterval(() => this.setTime(timeDiff), 1000)
}
您应该将 setTimeInterval
绑定到您的组件,例如 this.mySetTimeInterval = setTimeInterval(() => {});
在其他任何地方,您都可以停止 运行 间隔:
clearInterval(this.mySetTimeInterval)
您的代码中没有 this.interval
,就像在 componentWillUnmount
中使用的那样,在函数 tick
中,我相信您想将 setInterval 调用的结果存储在一个变量中命名区间。正如@rebecca 所说,您可能应该使用
setTime(timeDiff) {
setState(/* To avoid race conditions */ function(){
return {
seconds: new Date().getSeconds(),
minutes: new Date().getMinutes(),
hours: timeDiff + new Date().getHours()
})
}
tick(timeDiff) {
this.interval = setInterval(() => this.setTime(timeDiff), 1000)
}
避免竞争条件