React未在子组件中显示更新状态

时间:2017-04-16 23:33:52

标签: javascript reactjs state

这是React tutorial的改编。 我的意图是使用一个或两个玩家的选择来自动迁移 选择动作。在这个阶段由于某种原因,没有选择正方形 使用handleMove(i)语句在this.setState({squares:this.state.squares, xIsNext: !this.state.xIsNext})的调用中捕获,可以从中看到 Button和Square组件中的两个console.log调用。

这是教程中使用的技术,所以我不确定为什么square数组不是 更新。我读了其他帖子和Facebook关于不变性的讨论 函数(在这种情况下是handleMove(i),正确吗?)必须在更改状态之前完成 反映在整体状态。调用其他组件中的console.log以及整个DOM 不反映广场上的点击次数。

谁能告诉我为什么这不起作用?谢谢。

JSBin

<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Tic Tac Toe</title>
<script src="https://unpkg.com/react@latest/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id='root'></div>
<script type='text/babel' >


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



class Board extends React.Component{
  renderSquare(i){
    console.log(this.props.squares);  
    return <Square value={this.props.squares[i]} onClick={() => this.props.onClick(i)} />
  }  

  render(){
    return(
    <div className="board">
    <div className="row">
        {this.renderSquare(0)}
        {this.renderSquare(1)}
        {this.renderSquare(2)}
    </div>
    <div className="row">
        {this.renderSquare(3)}
        {this.renderSquare(4)}
        {this.renderSquare(5)}
    </div>
    <div className="row">
        {this.renderSquare(6)}
        {this.renderSquare(7)}
        {this.renderSquare(8)}
    </div>
    </div>
    );
  }
}


class Game extends React.Component{

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

  onePlayer(){
    this.setState({onePlayerGame: true});
    return(
    document.getElementById('onePlayer').style.color = "yellow",
    document.getElementById('twoPlayer').style.color = "black"
    );
  }


  twoPlayer(){
    this.setState({ onePlayerGame: false});
    return(
    document.getElementById('onePlayer').style.color= "black",
    document.getElementById('twoPlayer').style.color= "yellow"
    );

  }

  handleMove(i){
    const squares = this.state.squares.slice();
    squares[i] = this.state.xIsNext ? 'X':'O';


    this.setState({
      squares: this.state.squares,
      xIsNext: !this.state.xIsNext
    })
  }



  render(){
    return(
    <div id="main">
      <div>
       <button className="gameSelect" id="onePlayer" value={this.state.onePlayerGame} onClick={() => this.onePlayer()}  >One Player</button>
       <button className="gameSelect"  id="twoPlayer"value={this.state.onePlayerGame} onClick={() => this.twoPlayer()}  >Two Players</button>
      </div>

      <Board 
        squares={this.state.squares} 
        onClick={(i) => this.handleMove(i)} />

    </div>
    );
  }
}



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



</script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

已捕获选区,但您未在squares中保存state的新值。

handleMove(i){
    const squares = this.state.squares.slice();
    squares[i] = this.state.xIsNext ? 'X':'O';


    this.setState({
      squares: this.state.squares, <----- You are not assigning the new value
      xIsNext: !this.state.xIsNext
    })
}

应该是

handleMove(i){
    const squares = this.state.squares.slice();
    squares[i] = this.state.xIsNext ? 'X':'O';


    this.setState({
      squares: squares,
      xIsNext: !this.state.xIsNext
    })
}

这是正确的jsbin