I am running this code and every time i click on an object the whole element tree re-renders.Since my handleClick method is inside the renderCard method, shouldn't the element i am clicking be the only one that re-renders. I am thinking it has to do with the individuality of the the renderCard method and since each one is not specific that's why all of them re-render, so should i pass as prop the number of the card i want to re-render?If not what's wrong?
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"));
Some extra info: The logs are used to identify my problem, disregard them. I know there may be some anti-patterns in there but i started last week with js so i am learning.ALSO VERY IMPORTANT i know that the handleclick method doesn't do anything and it setstates to object Object, this is a problem i will solve later
React's render functionality works like this;
setState
. With that in mind, consider how your code feeds into this flow; On the virtual dom render, your code is going to re-run the cardDraw
method, which produces a random result. This means that it will always produce a unique outcome, and always be re-rendered.
If you want to prevent this, you need to store the first outcome of cardDraw
in a location where you can reference the previous result, and therefore preserve the same render of the sub-components. The proper place to store this outcome is on the state.
I would create an array of size 10 on the state, and populate it with 10 calls to cardDraw
. Then reference this.state.cards[index]
whenever you need to retrieve a previously drawn card.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.