【问题标题】:Two loops in ReactJS instead of hardcodingReactJS 中的两个循环而不是硬编码
【发布时间】:2017-06-27 15:08:42
【问题描述】:

我尝试在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)} 9 次,而是想用两个循环替换它们或使用map(map()),但我写的所有东西看起来都比硬编码更糟糕。

有没有更好的方法来避免硬编码?

【问题讨论】:

  • 看看How to Ask。什么“看起来更糟”?情况如何更糟?它不工作吗?等等。编辑您的问题以进行相应的澄清。还有codereview.stackexchange.com 可能是解决此类问题的更好场所。
  • 看起来不错。
  • 您是否发现以下任何有用的答案?如果是,请考虑对他们进行投票并“接受”解决您的问题的那个(如果有的话)。

标签: javascript loops reactjs


【解决方案1】:

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

以下是一些建议:

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

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

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

// 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】:

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

    由于项目只是任意设置为0, 1, 2等,您可以从一个数组开始,然后使用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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 2014-01-14
      • 2013-01-11
      • 2014-01-24
      • 1970-01-01
      相关资源
      最近更新 更多