简体   繁体   English

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

[英]Conditional (ternary) Operator to set the state in ReactJS

i am new with Reactjs and doing a game to practice.I want to change the state inside a clickHandler function with a conditional Operator. 我是Reactjs的新手,正在做一个练习游戏。我想使用条件运算符更改clickHandler函数中的状态。 But don't now if i can do that and my game is not working properly. 但是现在不要,如果我可以这样做并且我的游戏无法正常运行。

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})
}

I need that the last line of this functions works in order to give the victory to the right player. 我需要此功能的最后一行才能发挥作用,以使合适的玩家获得胜利。

with console.log i realize that the value of hoursOne(hours player one needs to transport the gold) and hoursTwo is catched and the conditional operator sometimes works in the wrong way. 使用console.log我意识到hoursOne(一个玩家需要运输黄金的小时数)和hoursTwo的值被捕获了,条件运算符有时会以错误的方式工作。

Feel free to try the game: https://leonelav.github.io/star-wars-react/ 随意尝试游戏: https://leonelav.github.io/star-wars-react/ : https://leonelav.github.io/star-wars-react/

When we click Play the winner should be the player who transport the given amount of gold in less time. 当我们单击“ Play ,获胜者应该是在较短时间内运输给定数量的黄金的玩家。 All the travel is made at same speed and in each trip we need to add 1 hour more to charge the gold and another to descharge. 所有行程均以相同的速度进行,在每次行程中,我们需要多花1个小时来充值黄金,而又要充一次电。

You're breaking a React state rule: If you're setting state based on state, you must use the callback version of setState , not the version that accepts the state directly. 您正在违反React状态规则:如果要基于状态设置状态,则必须使用setState的回调版本, 而不是直接接受该状态的版本。 From the documentation 文档中

React may batch multiple setState() calls into a single update for performance. React可以将多个setState()调用批处理到单个更新中以提高性能。

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. 由于this.propsthis.state可以异步更新,因此您不应依赖于它们的值来计算下一个状态。

... ...

To fix it, use a second form of setState() that accepts a function rather than an object. 要解决此问题,请使用setState()的第二种形式,该形式接受函数而不是对象。

So you need to recast that as a single setState call returning the new state, something along these lines: 因此,您需要将其重铸为单个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;
    });
}

...or if you really want to use the conditional, you could use spread properties (a Stage 3 proposal, supported by transpilers, present in cutting-edge browsers like current Chrome and Firefox): ...或者如果您真的想使用条件,则可以使用传播属性(在当前浏览器(例如Chrome和Firefox)等尖端浏览器中提供的,由编译器支持的第3阶段建议):

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})
        };
    });
}

...but I wouldn't. ...但是我不会。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM