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

问题描述 投票:0回答:1

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

我让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'
    }
  }
reactjs
1个回答
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))
  }
© www.soinside.com 2019 - 2024. All rights reserved.