我正在尝试改编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;
就像我承诺的那样:https : //stackblitz.com/edit/react-jdfqfo(花了大约30分钟,但很有趣)
问题出在
<Dialog
open={this.state.hasBingo}
TransitionComponent={Transition}
>
-您有一个上升的过渡,但是即使open为false(状态更改时),它也始终停留在那儿,我将其删除并可以正常工作,但是您可以为该过渡添加处理程序,并使用Dialog onClose可以当open为false时将其删除。
-我为您做了一些修复,在您要更新状态的渲染器上,您不应该这样做(尝试在控制台上检查反应热度)。我在handleClick上添加了该逻辑:)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句