我正在运行此代码,每次单击一个对象时,整个元素树都会重新渲染。因为我的handleClick方法在renderCard方法内,所以我点击的元素不应该是唯一一个重新渲染的元素。我认为它与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所以我正在学习。非常重要我知道handleclick方法没有做任何事情它设置为对象Object,这是一个问题我会稍后解决
答案 0 :(得分:0)
React的渲染功能就像这样;
setState
更改。考虑到这一点,请考虑您的代码如何输入此流程;在虚拟dom渲染中,您的代码将重新运行cardDraw
方法,从而产生随机结果。这意味着它将始终产生一个独特的结果,并且总是被重新渲染。
如果要阻止这种情况,则需要将cardDraw
的第一个结果存储在可以引用先前结果的位置,从而保留子组件的相同渲染。存储此结果的适当位置在州。
我会在状态上创建一个大小为10的数组,并用10个cardDraw
调用填充它。每当您需要检索以前绘制的卡片时,请参考this.state.cards[index]
。