简单项目出错:TypeError:无法读取属性' 0'未定义的[反应]

时间:2017-12-13 21:05:13

标签: reactjs

我正在尝试构建一个简单的反应tic tac toe应用程序,并且我已经相当远但现在我收到了一个我无法调试的错误。

我觉得这与我的renderPlaySquare(i)方法设置方式有关,但之后我就迷失了......

playSquareStates状态是否未正确设置?

对不起,感谢您的帮助。

我在这里包含了所有代码,因为它不是很长,也不是错误。

以下是两个错误

Board.renderPlaySquare SRC / App.js:53

 50 | 
  51 | renderPlaySquare(i) {
  52 |     debugger;
> 53 |     return (
  54 |         <PlaySquare value={this.props.playSquareStates[i]} onClick={() => this.props.onClick(i)}
  55 |         />
  56 |     );

查看已编译 Board.render SRC / App.js:66

  63 | <div>
  64 |     {/* Sets the index of the board*/}
  65 |     <div className="board-row">
> 66 |         {this.renderPlaySquare(0)}
  67 |         {this.renderPlaySquare(1)}
  68 |         {this.renderPlaySquare(2)}
  69 |     </div>

这是我的主要项目

import React, {Component} from 'react';
// import ReactDOM from 'react-dom'
import './index.css'

// Functions for the game

function PlaySquare(props) {
    debugger;
    return (
        <button
            className="playSquare"
            onClick={props.onClick}>
            {props.value}
        </button>
    );
}

// Declare a winner
function whoIsTheWinner(combination) {

    const lines = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6],
    ];

    // Loop through combinations
    for (let i = 0; i < lines.length; i++) {

        const [a, b, c] = lines[i];

        if (combination[a] && combination[a] === combination[b] && combination[a] === combination[c]) {
            return combination[a];
        }
    }
    return null;
}


// Main classes for the game

// The main component of the game, where the
// squares live
class Board extends Component {

    renderPlaySquare(i) {
        debugger;
        return (
            <PlaySquare value={this.props.playSquareStates[i]} onClick={() => this.props.onClick(i)}
            />
        );
    }

    render() {

        // Create the buttons they are going to play on
        return (
            <div>
                {/* Sets the index of the board*/}
                <div className="board-row">
                    {this.renderPlaySquare(0)}
                    {this.renderPlaySquare(1)}
                    {this.renderPlaySquare(2)}
                </div>
                <div className="board-row">
                    {this.renderPlaySquare(3)}
                    {this.renderPlaySquare(4)}
                    {this.renderPlaySquare(5)}
                </div>
                <div className="board-row">
                    {this.renderPlaySquare(6)}
                    {this.renderPlaySquare(7)}
                    {this.renderPlaySquare(8)}
                </div>
            </div>
        );
    }
}

class Game extends Component {

    constructor(props) {
        super(props);
        this.state = {
            history: [{
                playSquareStates: Array(9).fill(null)
            }],
            xIsNext: true
        };
    }

    handleClick(i) {

        const historyAll = this.state.history;
        const currentGame = historyAll[historyAll.length - 1];
        const currentGameConfiguration = currentGame.playSquareStates.slice();


        if (whoIsTheWinner(currentGameConfiguration) || currentGameConfiguration[i]) {
            return;
        }

        currentGameConfiguration[i] = this.state.xIsNext ? 'X' : 'O';

        // Now set the state AND history
        this.setState({
            history: historyAll.concat([{
                playSquareStates: currentGameConfiguration
            }]),
            xIsNext: !this.state.xIsNext,
        });
    }

    render() {

        const historyAll = this.state.history;
        const currentGame = historyAll[historyAll.length - 1];
        const winner = whoIsTheWinner(currentGame.playSquareStates);

        let currentTurn;

        if (winner) {
            currentTurn = 'Winner: ' + winner;
        } else {
            currentTurn = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
        }

        return (
            <div className="game">
                <div className="game-board">
                    <Board
                    playSquares = {currentGame.playSquareStates}
                    onClick = {(i) => this.handleClick(i)}
                />
                </div>
                <div className="game-info">
                    <div>
                        {currentTurn}
                    </div>
                    <ol>
                        {/* TODO */}
                    </ol>
                </div>
            </div>
        );
    }
}

class App extends Component {
    render() {
        return (
            <div className="App">
                <header className="App-header">
                    <h1>Welcome to React my Tic Tac Toe App</h1>
                </header>
                <Game/>
            </div>

        );
    }
}

export default App;

1 个答案:

答案 0 :(得分:2)

Game组件中,您可以像这样呈现Board组件:

<Board
  playSquares = {currentGame.playSquareStates}
  onClick = {(i) => this.handleClick(i)}
/>

这会在prop的{​​{1}}组件上创建Board,而不是playSquares

因此,您应该使用:

playSquareStates