“ onClick”事件影响所有组件的状态,而不仅仅是一个

时间:2019-04-11 13:50:27

标签: reactjs

我正在尝试创建一个交互式网格,当您单击某个单元格时,它只会增加该特定单元格上的数字。相反,当我单击一个单元格时,整个网格将递增,而不是一个单元格。

我让React打印出被点击的按钮的ID。它仅输出一个(正确的)ID。我确保我传递了一个函数() => {}而不是直接调用它。尝试删除箭头功能会导致React抱怨this is undefined

我知道这可能不是制作交互式网格的最佳方法(我在开玩笑,这是最可怕的方法),但是请您忍受:

  handleCellClick(id) {
    let cells = this.state.cells.slice()
    cells[id].level = cells[id].level + 1 // Increment ONLY ONE CELL
    console.log(cells[id]) // Logging to console only outputs one id, but it changes all of them?
    this.setState({ cells: cells });
  }

  render() {
    return (
      <div className="board">
        {
          Array(resolution).fill(null).map((_, x) => { // Represents the rows
            return (
              <div className='cellRow' key={x}>
                {
                  Array(resolution).fill(null).map((_, y) => { // Represents the columns
                    let id = (x * resolution) + y
                    return (
                      <Cell
                        key={id}
                        onClick={() => { this.handleCellClick(id) }} // This is where it binds the click event
                        data={this.state.cells[id]}
                      />
                    )
                  })
                }
              </div>
            )
          })
        }
        <p> {this.state.debug} </p>
      </div>
    )
  }

我希望单击上面的代码在单击一个单元格时,只有该单元格应该增加,但是,当实际测试它时,它将增加所有单元格。

The array seems to be built properly.

连接到React DevTools显示每个单元在数组中都有不同的项。

这是构造函数。

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.handleCellClick = this.handleCellClick.bind(this);
    this.state = {
      cells: Array(resolution * resolution).fill({
        level: 0,
        owner: null,
      }), // 5x5 for 25 in total
      turn: 'red'
    }
  }

1 个答案:

答案 0 :(得分:1)

您正在用相同的对象填充state.cells,因此,当您更改一个单元格对象的ID时,它会触发其他对象。您可以像下面那样更改构造函数并尝试

class Board extends React.Component {
   const cell = {
     level: 0,
     owner: null,
     turn: 'red'
   };
  constructor(props) {
    super(props);
    this.handleCellClick = this.handleCellClick.bind(this);
    this.state = {
      cells: Array(resolution * resolution).fill(Object.create(cell))
  }