React onClick在显示对话框后停止工作

问题描述 投票:0回答:1

我正在尝试改编tic-tac-toe React教程,并创建一个简单的宾果游戏(具有更改棋盘大小的能力)。我具有以下组件层次结构:

应用->游戏->棋盘->正方形

OnClick函数通过道具从游戏传递到广场。一旦计算出用户拥有宾果游戏,便会弹出一个带有按钮的对话框,使他们可以刷新游戏(在每个方块中渲染新项目并重置“ hasBingo”状态)。为此,我使用了一个一致的函数(refreshBoard),该函数在首次渲染木板和更改行属性时也会运行。当我单击对话框上的按钮时,开发板将刷新并准备好进行新的回合,但是正方形上的onClick事件不再被触发(尽管在开发工具中道具仍然存在)。

如果我通过在App中设置状态来更改行属性,则开发板将重新渲染并可以正常工作。对话框中我缺少什么吗?即使它不可见,它仍可以呈现在面板顶部并“劫持”点击吗?

这里的堆栈闪电战:https://react-jdfqfo.stackblitz.io

  class Game extends React.Component {

  constructor(props) {
    super(props);
    let numSquares = this.props.rows * this.props.rows;
    this.state = ( {
      numSquares : numSquares,
      squares : Array(numSquares).fill(false),
      phrases: Array(numSquares).fill(false),
      hasBingo: false,
      rows: this.props.rows,
    });
  }

  refreshBoard(rows) {
    //Reset the board
    let numSquares = rows * rows;
    this.setState({hasBingo:false,
     rows: rows,
     squares: Array(rows * rows).fill(false),
     phrases: Array(rows * rows).fill(false) })

    //Get new items from API to show on the board
    fetch('http://xxx')
        .then(res => res.json())
        .then((data) => {
          this.setState({ phrases: data.map(( {text}) => text) })
        })

  }

  componentDidMount() {
        this.refreshBoard(this.state.rows);
  }

      componentWillReceiveProps(nextProps) {
        //The App component state could change the number of rows, listen for that event
        this.setState({ rows: nextProps.rows });  
        this.refreshBoard(nextProps.rows);
      }



  handleClick(i) {
    const squares = this.state.squares.slice();
     if (this.state.hasBingo) {
       return;
     }
    squares[i] = !squares[i];
    this.setState({
        squares: squares,
      });
  }


   calculateBingo(squares, rows) {
   //Returns true for bingo, or null. Code removed for brevity


  return null;
}

  render() {

    let squares = this.state.squares;
    let winner = this.calculateBingo(squares, this.state.rows);
    let phrases = this.state.phrases;


    let Transition = React.forwardRef(function Transition(props, ref) {
      return <Slide direction="up" ref={ref} {...props} />;
    });


    let status;
    if (winner) {
      this.state.hasBingo = true;
    }

    return (
      <div className="game">
        <div className="game-board">

          <Board 
            squares={squares}
            phrases={phrases}
            rows={this.state.rows}
            onClick={(i) => this.handleClick(i)}/>
         </div>

        <div className="game-info">
          <Dialog
            open={this.state.hasBingo}
            TransitionComponent={Transition}
            keepMounted
            aria-labelledby="alert-dialog-slide-title"
            aria-describedby="alert-dialog-slide-description"
          >
        <DialogTitle id="alert-dialog-slide-title">{"BINGO"}</DialogTitle>
        <DialogContent>
          <DialogContentText id="alert-dialog-slide-description">
            Well done!
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => this.refreshBoard(this.state.rows)} color="primary">
            Start New Game
          </Button>
        </DialogActions>
      </Dialog>
        </div>

      </div>
    );
  }
}


export default Game;

reactjs
1个回答
0
投票

[就像我保证过的一样:https://stackblitz.com/edit/react-jdfqfo(花了大约30分钟,但很有趣)

问题出在

<Dialog
            open={this.state.hasBingo}
            TransitionComponent={Transition}
>

-您有一个上升的过渡,但是即使open为false,它也始终停留在那儿(当状态改变时),我将其删除并运行良好,但是您可以为该过渡添加一个处理程序,并且使用Dialog onClose,因此当open为false时可以将其删除。

-我为您进行了一些修复,正在更新状态的渲染器上,您不应该(尝试在控制台上检查反应热度)。我在handleClick上添加了该逻辑:)

© www.soinside.com 2019 - 2024. All rights reserved.