我正在尝试构建一个网络应用程序,计算每天应该为未来的旅行节省多少钱(我知道它可以通过一个简单的计算器轻松完成,但这是为了学习)。
我的问题是,当我在两个输入中输入成本和时间时,每日节省计算不会在DOM上实时呈现。
以下是发生的事情:
{this.state.totalCost}
和{this.state.timeLeft}
{this.state.dailyCost}
呈现"一次更改"延迟(即成本= 100,剩余天数= 10. 我需要输入其他内容,例如在成本中添加0以在DOM中呈现作为正确结果的计算。)感谢您的帮助!我希望我以一种可以理解的方式解释。
我的代码:
class App extends Component {
constructor() {
super();
this.state = {
totalCost: 0,
timeLeft: 0,
dailyCost: 0,
}
}
updateDailySavings() {
if (this.state.timeLeft !== 0) {
this.setState({dailyCost: (this.state.totalCost / this.state.timeLeft).toFixed(2)});
} else {
this.setState({dailyCost: 0});
}
}
changeCost(newCost) {
this.setState({totalCost: Math.round(newCost)});
this.updateDailySavings()
}
changeTimeLeft(newTimeLeft) {
this.setState({timeLeft: Math.round(newTimeLeft)});
this.updateDailySavings()
}
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to React</h1>
</header>
<Cost changeCost={this.changeCost.bind(this)}/>
<TimeLeft changeTimeLeft={this.changeTimeLeft.bind(this)}/> <br/>
<div>You have to save £{this.state.totalCost} in the next {this.state.timeLeft} days.<br/>
You have to save £{this.state.dailyCost} per day.
</div>
</div>
);
}
}
答案 0 :(得分:2)
你的onChange处理函数应该是
changeCost(newCost) {
this.setState({totalCost: Math.round(newCost)},
this.updateDailySavings);
}
changeTimeLeft(newTimeLeft) {
this.setState({timeLeft: Math.round(newTimeLeft)},
this.updateDailySavings);
}
来自docs,
setState()并不总是立即更新组件。它可以批量推迟更新或推迟更新。这使得在调用setState()之后立即读取this.state是一个潜在的陷阱。相反,使用componentDidUpdate或setState回调(setState(更新程序,回调)),其中任何一个都保证在应用更新后触发。
由于您希望在下一个setState调用中使用更新状态,因此应使用回调。
编辑:在删除@bennygenel指出的额外()
后更正了代码
答案 1 :(得分:1)
计算不会在DOM上实时呈现。
a)setState
为asynchronous,同一更新周期中的后续调用将覆盖以前的更新,之前的更改将会丢失。
因此,如果您想使用this.setState
值,则应使用回调函数。
this.setState({value: 'value'},() => {return : /*something here ..*/});
不是直接改变状态(this.state.someValue
),而是返回状态的新副本。
return { ...previousState, value: updated new state };
您可以阅读更多Here
答案 2 :(得分:0)
正如@bennygenel所指出的,setState是异步的,所以你应该这样做:
updateDailySavings() {
if (this.timeLeft !== 0) {
this.setState({dailyCost: (this.totalCost / this.timeLeft).toFixed(2)});
} else {
this.setState({dailyCost: 0});
}
}
changeCost(newCost) {
this.totalCost = Math.round(newCost);
this.setState({totalCost: this.totalCost});
this.updateDailySavings()
}
changeTimeLeft(newTimeLeft) {
this.timeLeft = Math.round(newTimeLeft);
this.setState({timeLeft: this.timeLeft});
this.updateDailySavings()
}
*请注意,可能不再需要两个以后的setStates,但我不知道你是否在使用它们之后
答案 3 :(得分:0)
对我来说,我使用了异步等待功能,并且工作得很好
async updateDailySavings() {
if (this.state.timeLeft !== 0) {
await this.setState({dailyCost: (this.state.totalCost / this.state.timeLeft).toFixed(2)});
} else {
await this.setState({dailyCost: 0});
}
}
async changeCost(newCost) {
await this.setState({totalCost: Math.round(newCost)});
this.updateDailySavings()
}
async changeTimeLeft(newTimeLeft) {
await this.setState({timeLeft: Math.round(newTimeLeft)});
this.updateDailySavings()
}
我希望它能为您提供帮助