2017-01-25 2 views
2

Моя цель состоит в том, чтобы функция handleClick() предупреждала квадратNum для любого квадратного объекта, который можно щелкнуть, как видно из кода ниже. Хотя реализация такого рода не работает. Сначала я попытался реализовать в соответствии с этим link, используя привязку, но не добился успеха.Проблема с использованием динамических атрибутов в действии

После дальнейших исследований я подозреваю, что проблема привязки существует, так как после щелчка созданный объект квадрата не идентифицирован, а скорее отображен html (фактическая кнопка).

Как таковой я создал атрибут data-id в отображаемой кнопке html, которая извлекает данные из квадратного объекта. Я приступил к осуществлению в соответствии с этим link.

К сожалению, я получаю сообщение об ошибке, которое getAttributes не определено, и не слишком уверен, что не так.

Наряду с решением проблемы getAttributes существует ли лучший способ реализовать это, поэтому соответствующий квадратNum идентифицируется при нажатии?

Заранее спасибо

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

ответ

3

Есть несколько проблем, с вашим примером, прежде всего, что вы не передаете реквизит для родительского класса. Кроме того, ваши обработчики onClick требуют функций. Функции ES6 arrow будут неявно связывать контекст, поэтому вы можете обернуть обработчики анонимным обратным вызовом. Что касается ошибки 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 
} 

Надеется, что это помогает!

+0

уверенный делает, спасибо :) –

Смежные вопросы