React中自动触发特定组件的OnClick事件
Automatically trigger an OnClick event of a specific component in React
我是 React 的初学者并且 Javascript 我正在尝试从头开始在 React 中创建扫雷器。我 运行 遇到了一个问题,我想复制扫雷器的功能,如果您单击周围有零地雷的图块,周围的图块将自动显示出来。但是,我无法弄清楚如何做到这一点。我的直觉是通过 id 获取周围的图块,并以某种方式手动触发 OnClick 事件,但据我所知,我的 Tile 组件不知道其他 Tile 组件,因此无法访问它们。而且我看不出如何从我的 Board 组件中做到这一点。任何建议将不胜感激!
板组件:
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
height: 8,
width: 8,
num_mines: 10
}
game_logic.initalizeGame(8,8,10);
game_logic.createGame();
}
render() {
var all_tiles = [];
for (var i = 0; i < this.state.height; i++) {
var row_tiles = [];
for (var j = 0; j < this.state.width; j++) {
row_tiles.push(<Tile key={'Tile ' + (i*this.state.height + j)} value={game_logic.tile_values[i][j]} />)
}
all_tiles[i] = row_tiles;
}
return (
<div>
{all_tiles.map((value, index) => {
return <div key={'Row ' + index}>{value}</div>
})}
</div>
)
}
}
export default Board;
磁贴组件:
class Tile extends React.Component {
constructor(props) {
super(props);
this.state = {
imgSrc: null,
imgAlt: '',
value: '',
};
}
tileClick = (e) => {
//left click: unveil tile
if (e.type === "click" && this.state.imgAlt === '') {
if (this.props.value < 0) {
this.setState({value: '', imgSrc: mine, imgAlt: "mine"});
}
else {
this.setState({value: this.props.value})
if (this.props.value === 0) {
//automatically left click all 8 surrounding tiles
}
}
}
//right click: mark or unmark tile
else if (e.type === "contextmenu") {
e.preventDefault();
if (this.state.value === '' && this.state.imgAlt !== "mine") {
if (this.state.imgAlt !== '') {
this.setState({imgSrc: null, imgAlt: ''});
}
else {
this.setState({imgSrc: flag, imgAlt: "flag"});
}
}
}
}
render() {
return (
<button
className="tile"
onClick={this.tileClick} onContextMenu={this.tileClick}>
<img src={this.state.imgSrc} alt={this.state.imgAlt} />
{this.state.value}
</button>
);
}
}
export default Tile;
您好,您必须更新线路
{this.state.value}
与下面
{this.state.value}
您需要 child 组件才能查看 parent 的 game_logic.tile_values
并对其进行操作。虽然可以从 parent 向下传递值并尝试在那里对它们做一些事情,但将点击处理程序放在 parent 所以一切都可以从那里轻松访问。
您还需要改变处理状态的方式。让每个单独的组件都有自己的状态将使 cross-component 通信变得非常困难,但这是您需要的,以便一个组件(tile)的更改影响其他 tile。在 parent.
中输入是否已揭牌的状态
class Board extends React.Component {
constructor(props) {
super(props);
game_logic.initalizeGame(8,8,10);
game_logic.createGame();
this.state = {
height: 8,
width: 8,
num_mines: 10,
revealed: Array.from(
{ length: 8 },
() => new Array(8).fill(false)
);
}
}
handleReveal = (x, y, visited = new Set()) => {
const tileKey = x + '_' + y;
// if out of bounds, or if visited before, don't do anything
if (visited.has(tileKey) || game_logic.tile_values[x]?.[y] === undefined) return;
visited.add(tileKey);
const isZero = game_logic.tile_values[x][y] === 0;
this.setState({
...this.state,
revealed: this.state.map(
(row, i) => i !== x
? row
: row.map(
(tileState, j) => y === j ? true : tileState
)
)
});
if (isZero) {
handleReveal(x - 1, y);
handleReveal(x + 1, y);
handleReveal(x, y - 1);
handleReveal(x, y + 1);
}
};
现在 parent 组件有 handleReveal
,将其传递给每个图块。单击左键时,调用向下传递的 handleReveal
,并让 children tiles 通过检查 parent 的 revealed
状态来决定要渲染的图像X 和 Y 是真还是假。
Tiles 可能不应该声明自己 除了 它们是否被标记。 imgSrc
可以直接从道具中确定,value
也是如此。最好不要在 parents 和 children 上重复状态 - 这样做会使事情变得混乱且难以处理,尤其是在更新时。
我是 React 的初学者并且 Javascript 我正在尝试从头开始在 React 中创建扫雷器。我 运行 遇到了一个问题,我想复制扫雷器的功能,如果您单击周围有零地雷的图块,周围的图块将自动显示出来。但是,我无法弄清楚如何做到这一点。我的直觉是通过 id 获取周围的图块,并以某种方式手动触发 OnClick 事件,但据我所知,我的 Tile 组件不知道其他 Tile 组件,因此无法访问它们。而且我看不出如何从我的 Board 组件中做到这一点。任何建议将不胜感激!
板组件:
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
height: 8,
width: 8,
num_mines: 10
}
game_logic.initalizeGame(8,8,10);
game_logic.createGame();
}
render() {
var all_tiles = [];
for (var i = 0; i < this.state.height; i++) {
var row_tiles = [];
for (var j = 0; j < this.state.width; j++) {
row_tiles.push(<Tile key={'Tile ' + (i*this.state.height + j)} value={game_logic.tile_values[i][j]} />)
}
all_tiles[i] = row_tiles;
}
return (
<div>
{all_tiles.map((value, index) => {
return <div key={'Row ' + index}>{value}</div>
})}
</div>
)
}
}
export default Board;
磁贴组件:
class Tile extends React.Component {
constructor(props) {
super(props);
this.state = {
imgSrc: null,
imgAlt: '',
value: '',
};
}
tileClick = (e) => {
//left click: unveil tile
if (e.type === "click" && this.state.imgAlt === '') {
if (this.props.value < 0) {
this.setState({value: '', imgSrc: mine, imgAlt: "mine"});
}
else {
this.setState({value: this.props.value})
if (this.props.value === 0) {
//automatically left click all 8 surrounding tiles
}
}
}
//right click: mark or unmark tile
else if (e.type === "contextmenu") {
e.preventDefault();
if (this.state.value === '' && this.state.imgAlt !== "mine") {
if (this.state.imgAlt !== '') {
this.setState({imgSrc: null, imgAlt: ''});
}
else {
this.setState({imgSrc: flag, imgAlt: "flag"});
}
}
}
}
render() {
return (
<button
className="tile"
onClick={this.tileClick} onContextMenu={this.tileClick}>
<img src={this.state.imgSrc} alt={this.state.imgAlt} />
{this.state.value}
</button>
);
}
}
export default Tile;
您好,您必须更新线路 {this.state.value} 与下面 {this.state.value}
您需要 child 组件才能查看 parent 的 game_logic.tile_values
并对其进行操作。虽然可以从 parent 向下传递值并尝试在那里对它们做一些事情,但将点击处理程序放在 parent 所以一切都可以从那里轻松访问。
您还需要改变处理状态的方式。让每个单独的组件都有自己的状态将使 cross-component 通信变得非常困难,但这是您需要的,以便一个组件(tile)的更改影响其他 tile。在 parent.
中输入是否已揭牌的状态class Board extends React.Component {
constructor(props) {
super(props);
game_logic.initalizeGame(8,8,10);
game_logic.createGame();
this.state = {
height: 8,
width: 8,
num_mines: 10,
revealed: Array.from(
{ length: 8 },
() => new Array(8).fill(false)
);
}
}
handleReveal = (x, y, visited = new Set()) => {
const tileKey = x + '_' + y;
// if out of bounds, or if visited before, don't do anything
if (visited.has(tileKey) || game_logic.tile_values[x]?.[y] === undefined) return;
visited.add(tileKey);
const isZero = game_logic.tile_values[x][y] === 0;
this.setState({
...this.state,
revealed: this.state.map(
(row, i) => i !== x
? row
: row.map(
(tileState, j) => y === j ? true : tileState
)
)
});
if (isZero) {
handleReveal(x - 1, y);
handleReveal(x + 1, y);
handleReveal(x, y - 1);
handleReveal(x, y + 1);
}
};
现在 parent 组件有 handleReveal
,将其传递给每个图块。单击左键时,调用向下传递的 handleReveal
,并让 children tiles 通过检查 parent 的 revealed
状态来决定要渲染的图像X 和 Y 是真还是假。
Tiles 可能不应该声明自己 除了 它们是否被标记。 imgSrc
可以直接从道具中确定,value
也是如此。最好不要在 parents 和 children 上重复状态 - 这样做会使事情变得混乱且难以处理,尤其是在更新时。