ReactJS 中的两个循环而不是硬编码

IT技术 javascript loops reactjs
2021-05-18 06:53:59

我尝试在ReactJS 教程 Tic-tac-toe game 中完成额外的练习

现在我有这个代码:

class Board extends React.Component {
renderSquare(i) {
    return (
        <Square
            value={this.props.squares[i]}
            onClick={() => this.props.onClick(i)}
        />
    );
}

render() {
    return (
        <div>
            <div className="board-row">
                {this.renderSquare(0)}
                {this.renderSquare(1)}
                {this.renderSquare(2)}
            </div>
            <div className="board-row">
                {this.renderSquare(3)}
                {this.renderSquare(4)}
                {this.renderSquare(5)}
            </div>
            <div className="board-row">
                {this.renderSquare(6)}
                {this.renderSquare(7)}
                {this.renderSquare(8)}
            </div>
        </div>
    );
}

}

{this.renderSquare(x)}我不想硬编码9 次,而是想用两个循环替换它们或使用,map(map())但我写的所有内容看起来都比硬编码更糟糕。

有没有更好的方法来做到这一点并避免硬编码?

2个回答

使用循环可能更好的主要原因是因为循环更通用。

这里有一些建议:

您可以将每行的行数和平方数保存在两个变量中,这些变量可以用作循环限制,然后调整网格只需要更新这两个变量。

将代码拆分为几个方法也可以将其清理干净。

这是一个带有循环的示例:

// these can also be passed in as `props` 
// if you want to use them like `<Board totalRows={3} squaresPerRow={3} squares={...}/>`
const totalRows = 3;
const squaresPerRow = 3;

class Board extends React.Component {
  renderSquare(i) {
    // ...
  }

  renderRow(row) {
    const squares = [];
    const offset = row * squaresPerRow; // this makes sure first row is 0,1,2, second row is 3,4,5, etc.
    for (let s = 0; s < squaresPerRow; s++) {
      squares.push(
        this.renderSquare(offset + s);
      );
    }
    return (
      <div className="board-row">
        {squares}
      </div>
    )
  }

  render() {
    const rows = [];
    for (let r = 0; r < totalRows; r++) {
      rows.push(
        this.renderRow(r)
      );
    }
    return <div>{rows}</div>;
  }
}

您可以创建 2 个地图,一个遍历每一行,一个遍历一行中的每个项目。

由于项目只是随意设置为0, 1, 2etc,因此您可以从一个数组开始,然后使用reduce().

这也允许您动态添加行,而不必指定它们,同时也不需要每行包含 3 个项目。


像这样的东西:

class MyApp extends React.Component {

  constructor() {
    super();
    this.state = {
      arr: [0, 1, 2, 3, 4, 5, 6, 7, 8]
    };
  }

  renderSquare(item) {
    return <span>{item}</span>;
  }

  render() {
    let arr = this.state.arr.reduce((acc, item) => {
      let group = acc.pop();
      if (group.length == 3) {
        acc.push(group);
        group = [];
      }
      group.push(item);
      acc.push(group);
      return acc;
    }, [[]]);
    return ( 
      <div>
        {arr.map(group => {
          return (
            <div className="board-row">
              {group.map(item => this.renderSquare(item))}
            </div>
          );
        })
      }
      </div>
    );
  }
}

ReactDOM.render(<MyApp />, document.getElementById("myApp"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="myApp"></div>