【问题标题】:Issue Utilizing Dynamic Attributes in React在 React 中使用动态属性的问题
【发布时间】:2017-06-10 02:33:55
【问题描述】:

我的目标是让函数 handleClick() 提醒 squareNum 点击任何方形对象,如下面的代码所示。虽然这样的实施是行不通的。起初,我尝试按照这个 link 通过绑定来实现 - 但没有成功。

经过进一步研究,我怀疑存在绑定问题,因为单击时创建的方形对象未识别,而是呈现的 html(实际按钮)。

因此,我在呈现的按钮 html 中创建了 data-id 属性,该属性从方形对象中检索数据。我按照这个link进行了实施。

不幸的是,我得到了 getAttributes 未定义的错误,并且不太确定出了什么问题。

除了getAttributes问题的解决方案,有没有更好的方法来实现这个,所以点击时识别出各自的squareNum?

提前致谢

CODEPEN

代码

class Square extends React.Component {
  //constructor
  constructor() {
    super();
    this.state = {
      value: null,
      squareNum: null,
    };
  }

  render() {
    return (
      //<button className="square" onClick = {() => this.setState({value: 'X'})}>
      //      <button className = "square" data-id = {this.props.squareNum} onClick = {() => this.props.onClick()}>
      <button className="square" data-id = {this.props.squareNum} onClick = {this.onClickSquare()}>
          {this.props.value}
      </button>
    );
  }

  onClickSquare() {
    this.props.onClick(this.props.squareNum);
  }
}

class Board extends React.Component {
  constructor() {
    super();
    this.state = {
      squares: Array(9).fill(null),
    };
  }

  renderRow(i) {
    var rowSquare = [];
    var square;

    //{objects.map((o, i) => <ObjectRow obj={o} key={i}/>}

    // create row of 3, creating square elements in array then return array
    for(var iterator = i; iterator < i+3; iterator++) {
      square = <Square key = {iterator} squareNum = {iterator} value = {this.state.squares[iterator]} onClick = {() => this.handleClick}  />;
      rowSquare.push(square);
    }
    return <div className ="board-row"> 
        {rowSquare}
    </div>
  } // end of renderRow()

  render() {
    const status = 'Next player: X';
    return (
      <div>
        <div className="status">{status}</div>
        {this.renderRow(0)}
        {this.renderRow(3)}
        {this.renderRow(6)}
      </div>
    );
  }

   handleClick(squareId) {
    // utilize slice to copy not change state
    // want to keep mutating changes to setState only
    const squares = this.state.squares.slice();
    alert(squareId);
    //squares[i] = 'X';
    this.setState({squares: squares});

  } // end of handleClick

}

class Game extends React.Component {
  render() {
    return (
      <div className="game">
        <div className="game-board">
          <Board />
        </div>
        <div className="game-info">
          <div>{/* status */}</div>
          <ol>{/* TODO */}</ol>
        </div>
      </div>
    );
  }
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您的示例存在一些问题,主要是您没有将道具传递给父类。此外,您的 onClick 处理程序需要函数。 ES6 箭头函数将隐式绑定上下文,因此您可以将处理程序包装在匿名回调中。至于getAttributes 错误,我的猜测是您试图在 DOM 中查询该属性,但您没有正确选择元素或保留对它的引用。无论如何,其余的应该相当简单,您根本不需要使用 data-id 属性。见https://codepen.io/anon/pen/Kavmyz?editors=0010

    class Square extends React.Component {
      //constructor
      constructor(props) {
        super(props);
        this.state = {
          value: null,
          squareNum: null,
        };
      }
    
      render() {
        return (
          <button className="square" onClick = {() => this.onClickSquare()}>
              {this.props.value}
          </button>
        );
      }
    
      onClickSquare() {
        this.props.onClick(this.props.squareNum);
      }
    }
    
    class Board extends React.Component {
      constructor() {
        super();
        this.state = {
          squares: Array(9).fill(null),
        };
      }
    
      renderRow(i) {
        var rowSquare = [];
        var square;
    
        // create row of 3, creating square elements in array then return array
        for(var iterator = i; iterator < i+3; iterator++) {
          square = ( <Square 
                     key={iterator}
                     squareNum={iterator}
                     value={this.state.squares[iterator]}
                     onClick={(squareNum) => this.handleClick(squareNum)}  />);
          rowSquare.push(square);
        }
        return <div className ="board-row"> 
            {rowSquare}
        </div>
      } // end of renderRow()
    
      render() {
        const status = 'Next player: X';
        return (
          <div>
            <div className="status">{status}</div>
            {this.renderRow(0)}
            {this.renderRow(3)}
            {this.renderRow(6)}
          </div>
        );
      }
    
       handleClick(squareId) {
        // utilize slice to copy not change state
        // want to keep mutating changes to setState only
        const squares = this.state.squares.slice();
        squares[squareId] = squareId;
        this.setState({squares: squares});
    
      } // end of handleClick
    }
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2010-11-11
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 2010-12-24
      • 2013-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多