0
votes

I´m trying to do a tic-tac-toe game in React to learn the framework basics and I was wondering how to make the machine change the textContent of the "following" event.target after my initial function is called:

onClickCardUser = (event) => {

        event.preventDefault();
        event.stopPropagation();

        event.target.textContent = 'X';

        //this.onClickCardMachine()
}

What I am doing there is just putting an "X" on the card that the user has clicked. So what I want to do next once that "x" has been written is call the onClickCardMachine function so it can put an "O" on the following card.

How to do that? I am not specially interested in if this solution gets me very close to a doing a tic-toe-game but just was very curious to learn if this could be done.

export default class Box extends React.Component {

    onClickFichaUser = (event) => {

            event.preventDefault();
            event.stopPropagation();

            event.target.textContent = 'X';

            this.onClickFichaMachine()
    }

    onClickFichaMachine = () => {

        console.log('now machine should do an "O" ')
    }

    render() {
        return (
            <div className="box">
                <Card id={1} onClick={this.onClickFichaUser} />
                <Card id={2} onClick={this.onClickFichaUser} />
                <Card id={3} onClick={this.onClickFichaUser} />

                <Card id={4} onClick={this.onClickFichaUser} />
                <Card id={5} onClick={this.onClickFichaUser} />
                <Card id={6} onClick={this.onClickFichaUser} />

                <Card id={7} onClick={this.onClickFichaUser} />
                <Card id={8} onClick={this.onClickFichaUser} />
                <Card id={9} onClick={this.onClickFichaUser} />
            </div>
        )
    }
}

The child element:

export default class Card extends React.Component{

    render(){
        return (
            <div>
                <button id={this.props.id} onClick={this.props.onClick} className="card">{this.props.dibujo}</button>
            </div>
        )
    }
}
1

1 Answers

1
votes

You should keep track of which the current player is (machine or user). You can do this by using your component state. Here is an example:

class Card extends React.Component {

  render() {
    return (<div>
      <button id={this.props.id} onClick={this.props.onClick} className="card">{this.props.dibujo}</button>
    </div>)
  }
}

class Box extends React.Component {

  state = {
    player: 'user'
  }

  onClickFichaUser = (event) => {
    event.preventDefault();
    event.stopPropagation();
    event.target.disabled = true;
    event.target.textContent = this.state.player === 'user'
      ? 'X'
      : 'O';

    this.setState(state => ({
      player: state.player === 'user'
        ? 'machine'
        : 'user'
    }))
  }

  render() {
    return (<div className="box">
      <Card id={1} onClick={this.onClickFichaUser}/>
      <Card id={2} onClick={this.onClickFichaUser}/>
      <Card id={3} onClick={this.onClickFichaUser}/>

      <Card id={4} onClick={this.onClickFichaUser}/>
      <Card id={5} onClick={this.onClickFichaUser}/>
      <Card id={6} onClick={this.onClickFichaUser}/>

      <Card id={7} onClick={this.onClickFichaUser}/>
      <Card id={8} onClick={this.onClickFichaUser}/>
      <Card id={9} onClick={this.onClickFichaUser}/>
    </div>)
  }
}

ReactDOM.render(< Box />, document.getElementById('root'));
.box {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  grid-gap: 10px;
}

.box div {
  background-color: dodgerblue;
  display: flex;
  align-items: center;
  justify-content: center;
}

.box div button {
  width: 50%;
  height: 50%;
  cursor: pointer;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>