2017-03-03 11 views
0

私は反応がとても新しく、私と一緒に裸でいます。私はConnect 4ゲームを構築しようとしています。ボードコンポーネントには7つのColumnコンポーネントすべてが6つのSpaceコンポーネントを含んでいます。すべての列にはその上にドロップボタンがあり、これを使用して列に項目をドロップします。 「赤」と「黒」のプレイヤーを交互に切り替えるために、私はブール値を返す状態「redOrBlue」を作成しました。React setStateは、呼び出されたときにコンポーネントを2回レンダリングします。

一言で言えば、ドロップボタンをクリックすると、 "redOrBlue"の値を切り替えて、その順番を維持したいと思います。私はsetState({redOrBlue:!this.state.redOrBlue}}にonClick関数を設定しましたが、この関数を呼び出すと、ボタンがクリックされた列のすぐ下に余分な列が描画されます。私は、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> 
    ) 
    } 
} 

答えて

0

:このような何かを試してみてください値。

は*、this.state.a = '' or this.state.a.push({})によってstate変数の変更を行わない、常に不変としてstate値を処理し、値を変更するだけsetStateを使用しないでください。

* 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> 
    ) 
} 
+0

これは事を非常に明確にするのに役立ちました。ありがとうございました! –

+0

@IanSpringerはあなたを助けてうれしいです:) –

0

レンダリング機能から{this.makeRow()}を削除します。あなたがやっていることは、コンポーネントにレンダリングされるたびに、むしろ非公式な方法で、状態に別の行を追加することだけです。

*すべての初決してストアui items状態変数で、state変数はデータのみが含まれている必要があり、:あなたのコードに変更する必要がある多くのものがありますが

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

オーケー? –

+0

いくつかのオプションがあります。あなたのコンストラクタからその関数を呼び出すのが最も簡単かもしれません。 – cssko

+0

@IanSpringer、私は自分の答えを編集して、それを行う方法を示しました。 – cssko

関連する問題