前端框架 使用React 开发一个井字棋(3) React函数组件

Isadora ·
更新时间:2024-11-01
· 695 次阅读

参考:https://blog.csdn.net/LU_ZHAO/article/details/104999318

函数组件

如果你想写的组件只包含一个 render 方法,并且不包含 state,那么使用函数组件就会更简单。我们不需要定义一个继承于 React.Component 的类,我们可以定义一个函数,这个函数接收 props 作为参数,然后返回需要渲染的元素。函数组件写起来并不像 class 组件那么繁琐,很多组件都可以使用函数组件来写。

把 Square 类替换成下面的函数:

function Square(props) { return ( ); } 轮流落子

现在井字棋还有一个明显的缺陷有待完善:目前还不能在棋盘上标记 “O”。

我们将 “X” 默认设置为先手棋。你可以通过修改 Board 组件的构造函数中的初始 state 来设置默认的第一步棋子:

class Board extends React.Component { constructor(props) { super(props); this.state = { squares: Array(9).fill(null), xIsNext: true, }; }

棋子每移动一步,xIsNext(布尔值)都会反转,该值将确定下一步轮到哪个玩家,并且游戏的状态会被保存下来。我们将通过修改 Board 组件的 handleClick 函数来反转 xIsNext 的值:

handleClick(i) { const squares = this.state.squares.slice(); squares[i] = this.state.xIsNext ? 'X' : 'O'; this.setState({ squares: squares, xIsNext: !this.state.xIsNext, }); }

接下来修改 Board 组件 render 方法中 “status” 的值,这样就可以显示下一步是哪个玩家的了:

render() { const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O'); return ( // 其他部分没有改变

现在你整个的 Board 组件的代码应该是下面这样的:

class Board extends React.Component { constructor(props) { super(props); this.state = { squares: Array(9).fill(null), xIsNext: true, }; } handleClick(i) { const squares = this.state.squares.slice(); squares[i] = this.state.xIsNext ? 'X' : 'O'; this.setState({ squares: squares, xIsNext: !this.state.xIsNext, }); } renderSquare(i) { return ( this.handleClick(i)} /> ); } render() { const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O'); return (
{status}
{this.renderSquare(0)} {this.renderSquare(1)} {this.renderSquare(2)}
{this.renderSquare(3)} {this.renderSquare(4)} {this.renderSquare(5)}
{this.renderSquare(6)} {this.renderSquare(7)} {this.renderSquare(8)}
); } }
判断出胜者

至此我们就可以看出下一步会轮到哪位玩家,与此同时,我们还需要显示游戏的结果来判定游戏结束。拷贝如下 calculateWinner 函数并粘贴到文件底部:

function calculateWinner(squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6], ]; for (let i = 0; i < lines.length; i++) { const [a, b, c] = lines[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a]; } } return null; }

传入长度为 9 的数组,此函数将判断出获胜者,并根据情况返回 “X”,“O” 或 “null”。

接着,在 Board 组件的 render 方法中调用 calculateWinner(squares) 检查是否有玩家胜出。一旦有一方玩家胜出,就把获胜玩家的信息显示出来,比如,“胜者:X” 或者“胜者:O”。现在,我们把 Board 的 render 函数中的 status 的定义修改为如下代码:

render() { const winner = calculateWinner(this.state.squares); let status; if (winner) { status = 'Winner: ' + winner; } else { status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O'); } return ( // 其他部分没有修改

最后,修改 handleClick 事件,当有玩家胜出时,或者某个 Square 已经被填充时,该函数不做任何处理直接返回:

handleClick(i) { const squares = this.state.squares.slice(); if (calculateWinner(squares) || squares[i]) { return; } squares[i] = this.state.xIsNext ? 'X' : 'O'; this.setState({ squares: squares, xIsNext: !this.state.xIsNext, }); }
作者:LU_ZHAO



井字棋 前端 前端框架 React 数组 框架

需要 登录 后方可回复, 如果你还没有账号请 注册新账号