我陷入了 tic-tac-toe 教程增强功能,并想知道为什么以下代码使用
renderBoard()
函数会崩溃。另外,我在浏览器中使用 codepen,并且运行时堆栈转储似乎没有提供除问题发生位置之外的任何有用信息 - 任何建议表示赞赏。
class Board extends React.Component {
renderSquare(i) {
return (
<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
);
}
renderRow(row) {
return (
<div className="board-row">
{this.renderSquare(row * 3 + 0)}
{this.renderSquare(row * 3 + 1)}
{this.renderSquare(row * 3 + 2)}
</div>
);
}
renderBoard() {
const rows = [];
for (row=0; row<3; row++)
{
rows.push(this.renderRow(row));
}
return ({rows});
}
render() {
return (
<div>
{this.renderBoard()}
</div>
);
}
}
该代码有一些问题。
renderBoard() {
const rows = [];
for (row=0; row<3; row++) // <--- (1) You haven't declared `row`. Put the word `let` in front to declare it
{
rows.push(this.renderRow(row));
}
return ({rows}); // <--- (2) You're returning an object with 1 property called rows. You should just be returning the array as-is.
}
并且(3)渲染数组时,必须添加一个
key
。
renderRow(row) {
return (
<div key={row} className="board-row">
{this.renderSquare(row * 3 + 0)}
{this.renderSquare(row * 3 + 1)}
{this.renderSquare(row * 3 + 2)}
</div>
);
}
@mpen 目前已经提到了您的代码本身的问题。
尽管我会回答最初提出的问题,即关于使用两个循环来创建增强功能,因为您的代码本身仅使用一个循环而不是两个循环。
我目前只是将大小作为参数传递以提高灵活性(这样,如果您将来想更改 for 循环的大小以创建 5x5 井字游戏,则可以轻松调整)。
注意:我相信作者正在遵循本教程: https://reactjs.org/tutorial/tutorial.html
class Board extends React.Component {
renderSquare(i) {
return (
<Square
key={i}
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
);
}
renderBoard(size) {
const board = [];
for (let i = 0; i < size; i++) {
let row = [];
for (let j = 0; j < size; j++) {
row.push(this.renderSquare(i * size + j));
}
board.push(
<div key={i} className="board-row">
{row}
</div>
)
}
return board;
}
render() {
return (
<div>
{this.renderBoard(3)}
</div>
);
}
}
无需编写renderRow函数。这是我的做法:
...
let board = [];
for (let i = 0; i < 3; i++) {
let row = [];
for (let j = 0; j < 3; j++) {
row.push(<Square value={squares[i*3+j]} onSquareClick={() => handleClick(i*3+j)} />);
}
board.push(<div className="board-row">{row}</div>);
}
return <>
<div className="status">{status}</div>
{board}
</>;
...