2017-09-12 8 views
0

私はこのコードを実行しています。オブジェクトをクリックするたびに要素ツリー全体が再描画されます。私のhandleClickメソッドがrenderCardメソッドの内側にあるので、再レンダリングするのは1つだけです。私はそれがrenderCardメソッドの個性と関係していると思っています。それぞれが特定のものではないので、それらのすべてが再レンダリングされるのですから、再レンダリングしたいカードの番号を指定して渡しますか?何が間違っているのではない?ツリーの再レンダリングの反応

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import './index.css'; 

class CardNEW extends React.Component{ 

    render(){ 
     return(
      <span className={"card rank-" + this.props.rank+" "+this.props.suit+""}> 
         <span className="rank">{this.props.rank}</span> 
         <span className="suit"></span> 
        </span> 
      ); 
    } 
    } 


class Game extends React.Component{ 
    constructor(){ 
     super(); 
     this.newdeck=this.deckCreator(); 
     this.handleClick = this.handleClick.bind(this); 
    } 
    deckCreator(){ 
     const deckdiamonds=[]; 
     const deckspades=[]; 
     const deckclubs=[]; 
     const deckhearts=[]; 
     for(let i=0;i<13;i++){ 
     if(i==0){ 
      deckspades.push(['a','spades']) 
     }else if(i==10){ 
      deckspades.push(['j','spades']) 
     }else if(i==11){ 
      deckspades.push(['q','spades']) 
     }else if(i==12){ 
      deckspades.push(['k','spades']) 
     }else{ 
     deckspades.push([i+1,'spades']) 
     } 
     } 
     for(let k=0;k<13;k++){ 
     if(k==0){ 
      deckdiamonds.push(['a','diams']) 
     }else if(k==10){ 
      deckdiamonds.push(['j','diams']) 
     }else if(k==11){ 
      deckdiamonds.push(['q','diams']) 
     }else if (k==12) { 
      deckdiamonds.push(['k','diams']) 
     }else{ 
     deckdiamonds.push([k+1,'diams']) 
     } 
     } 
     for(let l=0;l<13;l++){ 
     if(l==0){ 
      deckclubs.push(['a','clubs']) 
     }else if(l==10){ 
      deckclubs.push(['j','clubs']) 
     }else if(l==11){ 
      deckclubs.push(['q','clubs']) 
     }else if (l==12) { 
      deckclubs.push(['k','clubs']) 
     }else{ 
     deckclubs.push([l+1,'clubs']) 
     } 
    } 
     for(let m=0;m<13;m++){ 
     if(m==0){ 
      deckhearts.push(['a','hearts']) 
     }else if(m==10){ 
      deckhearts.push(['j','hearts']) 
     }else if(m==11){ 
      deckhearts.push(['q','hearts']) 
     }else if (m==12) { 
      deckhearts.push(['k','hearts']) 
     }else{ 
     deckhearts.push([m+1,'hearts']) 
     } 
     } 
     return deckdiamonds.concat(deckspades,deckclubs,deckhearts); 
    } 
    handleClick(i){ 
      this.setState({rank:1 ,suit:2}) 
      console.log('yo' + this.state); 
    } 

    cardDraw(deck){ 
    let cut=Math.floor((Math.random() * deck.length) + 0); 
    let card=deck.splice(cut, 1); 
    console.log('ya' + this.state); 
    return card; 
    } 

    renderCard(i){ 
     const newcard=this.cardDraw(this.newdeck); 
       return(
       <button onClick={this.handleClick}> 
        <span className="playingCards simpleCards"> 
         <CardNEW rank={newcard[0][0]} suit={newcard[0][1]}/>      
        </span> 
       </button>); 
    } 

    render() { 
    return (
     <span> 
     <span className="opponent-hand"> 
      {this.renderCard(1)} 
      {console.log('yei')} 
      {this.renderCard(2)}   
      {this.renderCard(3)} 
      {this.renderCard(4)} 
      {this.renderCard(5)} 
     </span> 
     <div className="my-hand"> 
      {this.renderCard(6)} 
      {this.renderCard(7)} 
      {this.renderCard(8)} 
      {this.renderCard(9)} 
      {this.renderCard(0)} 
     </div> 
     </span> 
    ); 
    } 
} 

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

いくつかの追加情報:ログは問題を特定するために使用されますが、無視してください。私はそこにいくつかの反パターンがあるかもしれないことを知っているが、私は先週jsで始めたので、私はlearning.ALSO非常に重要なことを知っているhandleclickメソッドは何もしていないとオブジェクトオブジェクトにsetstates、これは問題です後で解く

答えて

0

リアクトのレンダリング機能はこのように機能します。

  1. 状態はsetStateで変更されます。
  2. Reactは、 "virtual dom"で状態が変更されたコンポーネントの、目に見えないテスト再レンダリングを実行します。
  3. ステップ2の結果、リアクションは仮想ドーム上のすべてのサブコンポーネントも再レンダリングします。これは、非構成要素が見つかるまで再帰的に継続する。
  4. 仮想ドミノで再描画されたすべての要素に対して、反応して新しい結果と以前の結果が比較されます。
  5. 新しい結果が以前の結果と一致しない場合、reactはサブコンポーネントを再レンダリングします。

これを念頭に置いて、コードがどのようにこのフローにフィードされるかを考えてみましょう。バーチャルドームレンダーでは、あなたのコードはcardDrawメソッドを再実行し、ランダムな結果が得られます。これは、常にがユニークな結果を生み出し、常に再レンダリングされることを意味します。

これを防ぐには、前の結果を参照できる場所にcardDrawの最初の結果を格納する必要があります。したがって、サブコンポーネントの同じレンダリングが保持されます。この結果を保存するための適切な場所は州にあります。

ステートにサイズ10の配列を作成し、cardDrawを10回コールします。以前に描かれたカードを取り出す必要があるときはいつでも参照this.state.cards[index]を参照してください。

+0

私はあなたが提案したことを行い、再レンダリングの理由を理解しました。私が欲しいことをやり遂げることができるいくつかのさらなる変更と提案で、ありがとう –

関連する問題