首页 文章

React setState在调用时呈现组件两次

提问于
浏览
1

我正在尝试构建一个connect 4游戏,它有一个由7个Column组件组成的Board组件,每个组件都包含6个Space组件 . 每个列上方都有一个Drop按钮,用于将该块放入列中 . 为了在“红色”和“黑色”玩家之间交替,我创建了一个状态“redOrBlue”,它返回一个布尔值 .

简而言之,当单击“下拉”按钮时,我想切换“redOrBlue”的值以跟踪它的转向 . 我已经将onClick函数设置为setState({redOrBlue:!this.state.redOrBlue)},但是,调用此函数将导致react在单击按钮的列的正下方呈现一个额外的列 . 我知道setState会自动重新呈现DOM,但是如何保持它不会呈现组件的重复?谢谢你的帮助!

class Column extends Component{
  constructor(){
    super();
    this.state = {
      myArray: [],
      buttonArray: [],
      buttonNumber: null,
      newArray: [],
      redOrBlue: true
    }
  }
  makeRow(){
    var component = <Space className="space"/>
    for(var i = 0; i < 6; i++){
      this.state.myArray.push(component);
    }
  }

  handleClick(){
    var num = this.props.colNumber;
    var array = this.props.boardArray[num];
    var boolean = false;
    var color;
    if(this.state.redOrBlue === true){
      color = "red"
    }else{
      color = "black"
    }
    for(var i = 5; i > -1; i--){
      if(boolean === false){
        if(array[i] === null){
          array[i] = color;
          boolean = true;
        }
      }
    }
    this.setState({redOrBlue: !this.state.redOrBlue})
    console.log(array)
  }

  render(){
    {this.makeRow()}
    return(
      <div className="column">
        <DropButton onClick={() => this.handleClick()} id={'button-' + this.props.colNumber} buttonNumber={this.props.colNumber} className={this.props.className}/>
        {this.state.myArray.map(function(component, key){
          return component
        })}
      </div>
    )
  }
}

2 回答

  • 0

    从渲染功能中删除 {this.makeRow()} . 你所做的就是每次组件渲染时,以一种非犹太方法向状态中添加另一行 . 尝试这样的事情:

    constructor(){
        super();
        this.state = {
          myArray: [],
          buttonArray: [],
          buttonNumber: null,
          newArray: [],
          redOrBlue: true
        }
        this.makeRow();
      }
      makeRow(){
        var tempArray = [];
        var component = <Space className="space"/>
        for(var i = 0; i < 6; i++){
          tempArray.push(component);
        }
        this.setState({ myArray: tempArray }};
      }
    
  • 0

    您需要在代码中更改许多内容:

    *首先 neverui items 存储在状态变量中, state 变量应该只包含数据和值 .

    *永远不要通过 this.state.a = '' or this.state.a.push({})state 变量进行任何更改,始终将 state 值视为不可变,并仅使用 setState 更改值 .

    *总是在 render 内调用函数,如果你想创建 dynamically ,它将直接创建 ui part .

    从render调用 makeRow 方法,它将直接返回ui而不将其存储在状态变量中,如下所示:

    makeRow(){
        var component = [];
        for(var i = 0; i < 6; i++){
          component.push(<Space key={i} className="space"/>);
        }
        return component;
     }
    
    render(){
        return(
            <div className="column">
                <DropButton onClick={() => this.handleClick()} id={'button-' + this.props.colNumber}
                    buttonNumber={this.props.colNumber} className={this.props.className}/>
                {this.makerow()}
            </div>
        )
    }
    

相关问题