2016-12-14 75 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