我有以下组件负责一些事情
下面的代码在大约 80% 的时间里工作,事实上,它总是适用于至少三个不同的实例(选择一个动作,处理调度,选择另一个,再次调度,等等),但是在三个之后,(通常更多)一行会被跳过。
点击后,processMoves
函数被调用,它将处理步骤 2a 和 3。同样,这几乎总是有效,但有时行 let oppMoveObj = makeOppMoveSelection(opp)
被跳过,破坏它下面的所有内容。我知道它会跳过这一行,因为在那个函数内部,我有一个 debugger
和多个 console.log
语句,它们将在前三次或更多点击中被击中。代码如下
import React, { Component } from 'react';
import { connect } from 'react-redux';
import makeOppMoveSelection from '../../helpers/oppMoveSelection';
import { moveAction } from '../../helpers/moveHelper';
import './Move.css'
// PROPS MEHTODS
const mapStateToProps = (state) => {
return(
{battle: state.battle}
)
}
const mapDispatchToProps = (dispatch) => {
return({
chooseMove: (move, props) => processMoves(move, props),
executeMove: (move, attacker) => dispatch(moveAction(move, attacker)),
initiateMoveProcess: () => dispatch({type: 'MOVE_SELECTED'}),
completeMoveprocess: () => dispatch({type: 'MOVE_PROCESS_COMPLETE'})
})
}
// PROPS METHODS
// This will handle everything battle related after move selection. This includes...
// 1. Accepts the selected move from the User
// 2. Selects a move from the Opponent's available moves
// 3. Determines if they are shocked, they move last
// 4. Determines if any move has 'move first' effect, if so that move goes first
// 5. Compares speed to determine which move goes first
// 6. If any figure has 0 health after any move, the battle ends
// 7. After the moves are executed, applies any damage from status effects
function processMoves(moveObj, props){
// Assigns global values
let opp = props.battle.opp
let user = props.battle.user
// Selects a move that the opponent uses
let oppMoveObj = makeOppMoveSelection(opp)
// Removes the move selection screen for the message
props.initiateMoveProcess() // ERROR OCCURS HERE
// If someone is using a move that moves first
if (moveObj.effect == "move first" && oppMoveObj.effect != "move first"){
props.executeMove(moveObj, "user")
props.executeMove(oppMoveObj, "opp")
}
else if (oppMoveObj.effect == "move first" && moveObj.effect != "move first"){
props.executeMove(oppMoveObj, "opp")
props.executeMove(moveObj, "user")
}
// If someone is shocked the other goes first
else if (opp.status == "shocked" && user.status != "shocked"){
props.executeMove(moveObj, "user")
props.executeMove(oppMoveObj, "opp")
}
else if (opp.status != "shocked" && user.status == "shocked"){
props.executeMove(oppMoveObj, "opp")
props.executeMove(moveObj, "user")
}
// Handles everything else
else{
if (user.spd >= opp.spd){
props.executeMove(moveObj, "user")
props.executeMove(oppMoveObj, "opp")
}
else{
props.executeMove(oppMoveObj, "opp")
props.executeMove(moveObj, "user")
}
}
}
class Move extends Component{
handleClick = (event, props) => {
let indexofMove = parseInt((event.target.offsetParent.id.split("e")[1]), 10)
let selMove = this.props.battle.user.moves[indexofMove]
this.props.chooseMove(selMove, props)
}
render(){
return(
// get the index in as a prop from move container.
// This way, we can access the battle.user.moves and find the move that way for the dispatch.
// Meaning, the event would track the id of the div it clicked, and then use that id as the index
// of the move in the user.moves array to send in the dispatch and figure out all the damage
<div className={`MoveCard ${this.alterClassNameBasedOnCoolDown(this.props)}`} id={`MoveCard${this.props.index}`}
onClick = {(event) => this.handleClick(event, this.props)}>
<p id="name">{this.props.m.name}</p>
<p id="type">Type: {this.props.m.type}</p>
<p id="acc">Accuracy: {this.props.m.acc}</p>
<p id="dmg">{this.pow_or_heal(this.props.m.dmg)} {this.props.m.dmg}</p>
<p id="cool">Cooldown: {this.props.m.cool}</p>
</div>
)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Move)
我的 oppMoveSelection.js 文件看起来像这样...
export default function makeOppMoveSelection(opp){
let cooled = opp.moves.map( (move) => {
if (move.tillCooldown == 0){
return move
}
})
if (opp.hp < 50 ){
cooled.forEach(element => {
if (element.dmg < 0){
return element
}
});
}
else{
let len = cooled.length
let indexSel = Math.floor(Math.random() * len)
console.log("Inside opp move picker")
console.log(cooled)
console.log("Index selected: " + indexSel)
return opp.moves[indexSel]
}
}
我真的不知道是什么导致编译器完全跳过一行,而且由于从未定义过 oppMoveObj,我会收到错误 Uncaught TypeError: Cannot read property 'effect' of undefined
,即使它之前可以完美运行很多次。有人看到可能出了什么问题吗?
答案 0 :(得分:0)
如果 HP 低于 50,那些 console.logs 不会被击中,所以我们假设它在这里。
通常,我建议您在 debugger;
函数的第一行中编写 makeOppMoveSelection
,然后观察浏览器的开发工具中发生的情况,但这是我的猜测:
代码输入您的 .forEach
cooled.forEach(element => {
if (element.dmg < 0){
return element
}
});
并且在某些时候它会执行 return element
。但是您假设想要从 return
获得 makeOppMoveSelection
。但实际上,它只会从 return
中的箭头函数.forEach
。然后该循环继续运行下一次迭代,完成,然后 makeOppMoveSelection
结束,而没有遇到 return
语句。
这是使用 .forEach
的问题,老实说,我再也不会使用该功能了。自 2015 年 ES6 引入 for or
循环以来,这只是一个遗留的产物。
所以改用其中之一:
for (const element of cooled) {
if (element.dmg < 0){
return element
}
});
这将如您所愿。