我是Reactjs的新手并且正在练习游戏。我想用条件运算符更改clickHandler函数中的状态。但是现在不要,如果我能做到这一点,我的游戏运作不正常。
clickHandler(){
let tripsOne = Math.round(Math.round((this.state.amountOfGold / this.state.cargoOne) + 0.5))
let hoursOne= (tripsOne*2 + tripsOne*(this.state.distance/this.state.speedOne)).toFixed(2)
let tripsTwo = Math.round(Math.round((this.state.amountOfGold / this.state.cargoTwo) + 0.5))
let hoursTwo= (tripsTwo*2 + tripsTwo*(this.state.distance/this.state.speedTwo)).toFixed(2)
this.setState({tripsOne: tripsOne, hoursOne: hoursOne, tripsTwo: tripsTwo, hoursTwo: hoursTwo, showData: true})
hoursOne < hoursTwo ? this.setState({scoreOne: this.state.scoreOne +1, youWon:true}) : this.setState({scoreTwo: this.state.scoreTwo +1})
}
我需要这个功能的最后一行是为了给正确的玩家带来胜利。
使用console.log我意识到hoursOne的值(小时玩家需要传输黄金)和hoursTwo被捕获,条件运算符有时会以错误的方式工作。
随意尝试游戏:https://leonelav.github.io/star-wars-react/
当我们点击Play
时,获胜者应该是在更短的时间内运送给定金额的玩家。所有旅行都以相同的速度进行,每次旅行我们需要再增加1小时为黄金充电,而另一次则需要加油。
答案 0 :(得分:1)
您违反了React州规则:如果您是根据州设置州,则必须使用setState
的回调版本,不直接接受状态的版本。来自the documentation
React可以将多个
setState()
次调用批量处理为单个更新以提高性能。由于
this.props
和this.state
可能会异步更新,因此您不应该依赖它们的值来计算下一个状态。...
要修复它,请使用第二种形式的
setState()
接受函数而不是对象。
所以你需要重新设计一个setState
调用返回新状态,这些都是这样的:
clickHandler(){
this.setState(state => {
let tripsOne = Math.round(Math.round((state.amountOfGold / state.cargoOne) + 0.5))
let hoursOne= (tripsOne*2 + tripsOne*(state.distance/state.speedOne)).toFixed(2)
let tripsTwo = Math.round(Math.round((state.amountOfGold / state.cargoTwo) + 0.5))
let hoursTwo= (tripsTwo*2 + tripsTwo*(state.distance/state.speedTwo)).toFixed(2)
let newState = {
tripsOne: tripsOne, hoursOne: hoursOne, tripsTwo: tripsTwo, hoursTwo: hoursTwo, showData: true,
};
if (hoursOne < hoursTwo) {
newState.scoreOne = state.scoreOne + 1;
newState.youWon = true;
} else {
newSate.scoreTwo = state.scoreTwo + 1;
}
return newState;
});
}
...或者如果你真的想要使用条件,你可以使用传播属性(第3阶段提案,由转发器支持,存在于当前Chrome和Firefox等尖端浏览器中) :
clickHandler(){
this.setState(state => {
let tripsOne = Math.round(Math.round((state.amountOfGold / state.cargoOne) + 0.5))
let hoursOne= (tripsOne*2 + tripsOne*(state.distance/state.speedOne)).toFixed(2)
let tripsTwo = Math.round(Math.round((state.amountOfGold / state.cargoTwo) + 0.5))
let hoursTwo= (tripsTwo*2 + tripsTwo*(state.distance/state.speedTwo)).toFixed(2)
return {
tripsOne: tripsOne, hoursOne: hoursOne, tripsTwo: tripsTwo, hoursTwo: hoursTwo, showData: true,
...(hoursOne < hoursTwo ? {scoreOne: state.scoreOne + 1, youWon: true} : {scoreTwo: scoreTwo + 1})
};
});
}
......但我不会。