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

时间:2017-06-27 15:08:42

标签: javascript loops reactjs

我尝试在ReactJS tutorial 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)},而不是将map(map())硬编码9次。但是我写的所有内容都比硬编码更糟糕。这是一个更好的方法来避免硬编码吗?

2 个答案:

答案 0 :(得分:3)

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

以下是一些建议:

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

将代码拆分为几种方法也可能会将其清理干净。

以下是循环示例:

// 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>;
  }
}

答案 1 :(得分:0)

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

由于项目只是被任意设置为0, 1, 2等,您可以从一个数组开始,然后使用reduce()对它们进行分组。

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

这样的事情:

&#13;
&#13;
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"));
&#13;
<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>
&#13;
&#13;
&#13;