2016-12-14 74 views
1

我決定學習React並從官方教程開始。所有這些都是很好的,直到我達到我的代碼狀態。這個問題似乎是關於它的定義遊戲組件的渲染功能的當前屬性正方形,但我不知道爲什麼它標記爲錯誤反應教程給TypeError

function Square(props){ 
    return ( 
    <button className = "square" onClick = {() => props.onClick()}> 
     {props.value} 
    </button> 
); 
} 

class Board extends React.Component { 
    renderSquare(i) { 
    return <Square value = {this.props.squares[i]} onClick = {() => this.props.onClick(i)} />; 
    } 
    render() { 
    return (
     <div> 
     <div className="board-row"> 
      {this.renderSquare(0)} 
      {this.renderSquare(1)} 
      {this.renderSquare(2)} 
     </div> 
     <div className="board-row"> 
      {this.renderSquare(3)} 
      {this.renderSquare(4)} 
      {this.renderSquare(5)} 
     </div> 
     <div className="board-row"> 
      {this.renderSquare(6)} 
      {this.renderSquare(7)} 
      {this.renderSquare(8)} 
     </div> 
     </div> 
    ); 
    } 
} 

class Game extends React.Component { 
    constructor() { 
    super(); 
    this.state = { 
     history : [{ 
     squares : Array(9).fill(null) 
     }], 
     xIsNext : true 
    }; 
    } 
    handleClick(i){ 
    const history = this.state.history.slice(0, this.state.stepNumber); 
    const current = history[this.state.stepNumber]; 
    const squares = current.squares.slice(); 
    if(calculateWinner(squares) || squares[i]) { 
     return; 
    } 
    squares[i] = this.state.xIsNext ? 'X' : 'O'; 
    this.setState({ 
     history : history.concat([{ 
     squares : squares 
     }]), 
     xIsNext : !this.state.xIsNext, 
     stepNumber : 0, 
    }); 
    } 
    jumpTo(step){ 
    this.setState({ 
     stepNumber : step, 
     xIsNext : (step % 2) ? false : true, 
    }); 
    } 
    render() { 
    const history = this.state.history; 
    const current = history[this.state.stepNumber]; 
    const winner = calculateWinner(current.squares); 
    let status; 
    if(winner) { 
     status = 'Winner : ' + winner; 
    } 
    else { 
     status = 'Next Player : ' + (this.state.xIsNext ? 'X' : 'O'); 
    } 
    const moves = history.map((step, move) => { 
     const desc = move ? 'Move #' + move : 'Game start'; 
     return (
     <li key = {move}> 
      <a href="#" onClick={() => this.jumpTo(move)}>{desc}</a> 
     </li> 
    ); 
    }); 

    return (
     <div className="game"> 
     <div className="game-board"> 
      <Board 
      squares = {current.squares} 
      onClick = {(i) => this.handleClick(i)} 
      /> 
     </div> 
     <div className="game-info"> 
      <div>{status}</div> 
      <ol>{moves}</ol> 
     </div> 
     </div> 
    ); 
    } 
} 

// ======================================== 

ReactDOM.render(
    <Game />, 
    document.getElementById('container') 
); 

function calculateWinner(squares) { 
    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], 
    ]; 
    for (let i = 0; i < lines.length; i++) { 
    const [a, b, c] = lines[i]; 
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { 
     return squares[a]; 
    } 
    } 
    return null; 
} 

這是錯誤我得到

TypeError: Cannot read property 'squares' of undefined 
    at Game.render (pen.js:208:41) 
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:6336:34) 
    at ReactCompositeComponentWrapper._renderValidatedComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:6356:32) 
    at ReactCompositeComponentWrapper.wrapper [as _renderValidatedComponent] (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:12879:21) 
    at ReactCompositeComponentWrapper.mountComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:5969:30) 
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:12879:21) 
    at Object.mountComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:13613:35) 
    at ReactCompositeComponentWrapper.mountComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:5974:34) 
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:12879:21) 
    at Object.mountComponent (https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js:13613:35) 
+1

您是否嘗試在'Game'組件的'構造函數'內向'state'添加'stepNumber:0'? – DavidDomain

+1

@DavidDomain傻我 – rattleTrap

回答

2

因此,在您遊戲渲染功能,您與這些三行代碼就

const history = this.state.history; 
const current = history[this.state.stepNumber]; 
const winner = calculateWinner(current.squares); 

然而,在你的遊戲構造函數,你沒有在國家規定STEPNUMBER:

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

因此,當你做

const current = history[this.state.stepNumber]

你基本上做的是

const current = history[undefined]

這意味着,當你做

const winner = calculateWinner(current.squares)

你實際上是在做

const winner = calculateWinner(undefined.squares)

而且是你的問題。你需要在你的狀態下在構造函數中設置stepNumber。

+0

有沒有一種方法,我可以使用調試器與教程一起弄清楚這些錯誤,因爲理解拋出的錯誤似乎很難? – rattleTrap