繁体   English   中英

在哪里处理父子事件React

[英]Where to handle parent-child event React

我正在开始使用React基本概念,但不确定如何继续...

我正在尝试构建一个简单的Minesweeper游戏,我的结构是一个MinesweeperField包装器,其中高度,宽度和minesNumber作为道具,以及一个MinesweeperTile,其值(它是一个地雷/近距离地雷的数量)并作为道具进行了探索。

我的问题是,我不确定如何处理点击图块。 当探索图块以处理新的游戏状态时(例如,如果游戏结束或获胜),必须通知MinesweeperField组件,并且它还必须能够触发其他图块中的探索(例如,如果单击具有0个近地雷的图块,则必须自动探索所有相邻的图块)。

据我了解,有两种方法:

  • 处理在Tile上的单击,Tile通知Field,Field触发器也在相邻的Tile上进行探索-从Tile通知Field很容易,但是从Field调用Tile则需要使用引用,并且为每个Tile实例化一个不同的单击处理函数
  • 处理Field上的单击,Field更新在render中用于将isExplored prop分配给Tile的道具-由于我基于Field状态下的数组变量渲染Tile,因此我必须使用setState触发子Tile的重绘组件。

这是“ Handle Click on Field”版本中的渲染功能的简化示例:

return (
            <div className="minesweeper-wrapper">
                <div className="minesweeper-field" style={this.getDimensions()}>
                    {this.state.proximityMap.map(function(verticalRow, vIndex){
                        return verticalRow.map(function(tileValue, hIndex){
                            return <MinesweeperTile value={tileValue} hIndex={hIndex} vIndex={vIndex} onClick={this.exploreTile.bind(this, vIndex, hIndex, tileValue)} isExplored={this.state.explorationMap[vIndex][hIndex]} />
                        });    
                    })}
                </div>
            </div>
        );

这是explorerTile函数:

exploreTile(vIndex, hIndex, tileValue) {
        this.unveilTile(vIndex, hIndex);
        if (tileValue < 0) {
            this.gameOver();
        } else {
            if (tileValue === 0) {
                this.propagateTileExplore(vIndex, hIndex);
            }
        }
    }

this.state.proximityMap包含一些值,这些值指示有多少地雷靠近该图块/该图块是否是地雷。 this.state.explorationMap包含指示已浏览哪些图块的this.state.explorationMap值。

根据我的理解,这种方法的问题在于,如果我想重绘单个图块,则必须在Field上调用setState并更新this.state.explorationMap数组,该数组将重绘每个图块!

关于如何将重绘限制为单个图块的任何想法? 我应该继续探索“点击字段处理”方式还是回到“点击瓷砖处理”?

我从“单击瓷砖上的手柄”开始,但是在遇到“探索相邻瓷砖”问题时我停了下来。

另外,请不要使用jQuery / js技巧或骇客以非常规的方式解决此问题,这不是找到一种方法来实现,而是找到最合适的方法。 在扫雷游戏的背景下,它可能不会产生明显的变化,但是正如我所说的,这是出于训练目的:)

最合适的方法是让父母处理更改。 孩子们只需要知道被点击时给谁打电话以及他们的样子。 我使用React在生命游戏克隆中做了同样的事情。

CodePen链接

changeTile(row, col) {
    if (!this.state.isPlaying) {
      const newTile = this.state.board[row][col] === 1 ? 0 : 1;
      const newRow = [...this.state.board[row]];
      newRow.splice(col, 1, newTile);
      const newBoard = [...this.state.board];
      newBoard.splice(row, 1, newRow);
      this.setState({
        board: newBoard
      });
    }
  }

暂无
暂无

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

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