我正在尝试改编tic-tac-toe React教程,并创建一个简单的宾果游戏(具有更改棋盘尺寸的能力)。我具有以下组件层次结构:
App-> Game-> Board-> Square
OnClick函数通过道具从游戏传递到广场。一旦计算出用户拥有宾果游戏,便会弹出一个带有按钮的对话框,使他们可以刷新游戏(在每个方块中渲染新项目并重置“ hasBingo”状态)。为此,我使用了一个一致的函数(refreshBoard),该函数在首次渲染板时和行prop更改时也会运行。当我单击对话框上的按钮时,开发板将刷新并准备好进行新的回合,但是正方形上的onClick事件不再被触发(尽管在开发工具中道具仍然存在)。
如果我通过在App中设置状态来更改行属性,则开发板将重新渲染并可以正常工作。对话框中我缺少什么吗?即使看不见,它是否仍可以呈现在面板顶部并“劫持”点击?
此处可堆叠Stack Blitz: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;
答案 0 :(得分:0)
就像我保证过的那样:https://stackblitz.com/edit/react-jdfqfo(花了大约30分钟,但很有趣)
问题已经解决
<Dialog
open={this.state.hasBingo}
TransitionComponent={Transition}
>
-您有一个向上过渡的过渡,但是即使open为false,它也始终停留在那里(状态更改时),我将其删除并可以正常运行,但是您可以为并使用 Dialog onClose 进行转换,因此当open为false时可以将其删除。
-我为您做了一些修复,在您要更新状态的渲染器上,您不应该(尝试在控制台上检查反应热度)。我在handleClick上添加了该逻辑:)