簡體   English   中英

React setState在調用時呈現組件兩次

[英]React setState renders component twice when called

我正在嘗試構建一個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>
    )
  }
}

從渲染函數中刪除{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 }};
  }

您需要在代碼中更改許多內容:

*首先永遠不要ui items存儲在狀態變量中, state變量應該只包含數據和值。

*不要通過this.state.a = '' or this.state.a.push({})state變量進行任何更改,始終將state值視為不可變,並僅使用setState更改值。

*如果你想dynamically創建東西,總是在render中調用函數,直接創建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>
    )
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM