条件(三元)运算符在ReactJS中设置状态

时间:2017-11-30 11:43:10

标签: javascript random ecmascript-6

我是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小时为黄金充电,而另一次则需要加油。

1 个答案:

答案 0 :(得分:1)

您违反了React州规则:如果您是根据州设置州,则必须使用setState的回调版本,直接接受状态的版本。来自the documentation

  

React可以将多个setState()次调用批量处理为单个更新以提高性能。

     

由于this.propsthis.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})
        };
    });
}

......但我不会。