首页 > 解决方案 > 井字游戏应用程序中的撤消按钮使用 ReactJS

问题描述

我正在尝试在使用 reactJS 构建的 tic tac toe 应用程序中构建一个撤消按钮,为此我遵循了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();。我附上了截图这里 这是在 ReactJS 中实现 UNDO 按钮的正确方法,以便用户可以 UNDO 最后一步?如果没有,有人可以建议我更好的方法来实现这一目标吗?我是 ReactJS 的超级新手,我正在学习它,如果这是一个愚蠢的问题,请原谅我。

标签: javascriptreactjsreact-nativereact-reduxtic-tac-toe

解决方案


文档中我了解到您需要先在 handleClick 中调用 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();
    });
  } 

推荐阅读