Кнопка «Отменить» в приложении Tic Tac Toe Использование ReactJS - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь создать кнопку отмены в приложении Tic Tac Toe, созданном с использованиемactJS, для которого я следовал учебному пособию в Youtube :

Ниже приведен мой файл: App.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';

import './App.css';

import Status from'./components/Status';

class App extends Component {

  constructor(props){

    super(props)

    this.state = {

      board : Array(9).fill(null),
      player : null,
      winner : null,
      isUndoRedo: false
    }
  }

  checkWinner(){

    let winLines =
      [
        ["0", "1", "2"],
        ["3", "4", "5"],
        ["6", "7", "8"],
        ["0", "3", "6"],
        ["1", "4", "7"],
        ["2", "5", "8"],
        ["0", "1", "3"],
        ["0", "4", "8"],
        ["2", "4", "6"]
      ]

    this.checkmatch(winLines)
  }

  checkmatch(winLines){
    for (let index = 0; index < winLines.length; index++) {
      const [a,b,c]=winLines[index];
      let board = this.state.board;
      if(board[a] && board[a] === board[b] && board[a] === board[c]){
        alert('You won!');
        this.setState({
          winner : this.state.player
        })
      }
    }
  }

  handleClick(index){

    if(this.state.player && !this.state.winner){

      let newBoard = this.state.board

      if(this.state.board[index]===null){

        newBoard[index] = this.state.player

        this.setState({
          board: newBoard,
          player: this.state.player==="X" ? "O" : "X"
        })

        this.checkWinner()

      }
    }
  } 

  setPlayer(player){
    this.setState({player})

  }

  renderBoxes(){
    return this.state.board.map(
      (box, index) => 
      <div className="box" key={index} 
        onClick={()=> {this.handleClick(index)}}>
        {box}
      </div>
    )
  }

  reset(){

    this.setState({
      board : Array(9).fill(null),
      player :  null,
      winner : null

    })

  } 

  undo = (e) => { //Code for undoing the last move
    e.preventDefault();
    this.props.undoRedo.undo();
    this.setState({
      isUndoRedo: true,
    });
  };

  render() {

    return (

      <div className="container">
        <h1>Tic Tac Toe App</h1>

        <Status 
          player={this.state.player} 
          setPlayer={(e) => this.setPlayer(e)}
          winner = {this.state.winner}
        />

        <div className="board">

          {this.renderBoxes()}

        </div>

        <button className='reset' disabled ={!this.state.winner} onClick = {() => this.reset()}> Reset </button>
        <button className='reset' onClick = {this.undo}> Undo </button>

      </div>

    );
  }
}

App.propTypes = {
  undoRedo: PropTypes.object.isRequired, 
  val: PropTypes.string.isRequired,
  update: PropTypes.func.isRequired,
};

export default App;

Я перешел по этой ссылке при добавлении кнопки отмены, но при нажатии кнопки отмены выдает ошибку, сообщающую, что

TypeError: Не удается прочитать свойство'отменить' из неопределенного

для кода this.props.undoRedo.undo();.Я приложил скриншот here Это правильный способ реализации кнопки ОТМЕНА в ReactJS, чтобы пользователь мог ОТМЕНИТЬ последний ход?Если нет, то может ли кто-нибудь предложить мне лучший способ добиться этого?Я новичок в ReactJS и изучаю его, прошу прощения, если это глупый вопрос.

1 Ответ

0 голосов
/ 10 октября 2018

Из документации Я понимаю, что вам нужно сначала вызвать this.props.undoRedo.addStep в handleClick, а затем, когда вы нажмете на отмену, отмена будет работать.В вашей ручке кликните на это

handleClick(index){    
    if(this.state.player && !this.state.winner){    
      let newBoard = this.state.board    
      if(this.state.board[index]===null){    
        newBoard[index] = this.state.player    
        this.setState({
          board: newBoard,
          player: this.state.player==="X" ? "O" : "X"
        })    
        this.checkWinner()    
      }
    }
    setTimeout(() => {
       this.props.undoRedo.addStep();
    });
  } 
...