Javascript 向React中的状态数组添加值

Javascript 向React中的状态数组添加值,javascript,reactjs,Javascript,Reactjs,我正在努力完成两件事。第一,onClick,我正在向状态属性cardPairs添加值。我复制了state对象,并使用concat添加了一个值。我需要单击三下才能创建匹配项。第一次单击时,我得到了空数组,然后在接下来的两次正确单击时,我将得到一个匹配。使用推送在我的副本上不起作用,我得到一个“无法使用”错误,当尝试推送时,我得到“对象不可扩展”。如何在两次单击时匹配? 第二个问题是从UI中删除匹配的项 class CardCollectionTwo extends Component { co

我正在努力完成两件事。第一,onClick,我正在向状态属性cardPairs添加值。我复制了state对象,并使用concat添加了一个值。我需要单击三下才能创建匹配项。第一次单击时,我得到了空数组,然后在接下来的两次正确单击时,我将得到一个匹配。使用推送在我的副本上不起作用,我得到一个“无法使用”错误,当尝试推送时,我得到“对象不可扩展”。如何在两次单击时匹配? 第二个问题是从UI中删除匹配的项

class CardCollectionTwo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      hidden: false,
      cardPairs: []
    };
    this.compareCards = this.compareCards.bind(this);
  }

  compareCards(e) {
    const pairs = Object.freeze(this.state.cardPairs)
    console.log(pairs)
    this.setState({ cardPairs: pairs.concat(e.target.value) });
    console.log(this.state);
    if(pairs[0] === pairs[1] && pairs.length!== 0){
      console.log('MATCH')
    }else if(pairs.length === 2){
        this.setState(prevState => ({ cardPairs: [] }))
   }
 }
 render() {
    let cards = this.props.cardsEasy["cards"].map((item, index) => {
      return (
    <button
      style={btn}
      value={item}
      id={item}
      onClick={this.compareCards}
      key={item + index}
    >
      {item}
    </button>
  );
});
return <CardTwo cards={cards} />;
 }
   }

export default CardCollectionTwo;
class CardCollectionTwo扩展组件{
建造师(道具){
超级(道具);
此.state={
隐藏:假,
卡片对:[]
};
this.compareCards=this.compareCards.bind(this);
}
比较记录(e){
const pairs=Object.freeze(this.state.cardPairs)
console.log(对)
this.setState({cardPairs:pairs.concat(e.target.value)});
console.log(this.state);
if(pairs[0]==pairs[1]&&pairs.length!==0){
console.log('MATCH')
}else if(pairs.length==2){
this.setState(prevState=>({cardPairs:[]}))
}
}
render(){
let cards=this.props.cardsEasy[“cards”].map((项目,索引)=>{
返回(
{item}
);
});
返回;
}
}
导出默认cardcollection2;
Push和Object.freeze()

Object.freeze()
防止将元素添加到数组中(在您的情况下,通过推送)
Object.freeze()
防止添加、删除和更改应用于的任何对象(数组推送/修改、对象等)。要正确复制,可以使用
Array.slice()
this.state.cardPairs.slice()
),它返回源的浅拷贝

concat
不修改数组,而
push
修改数组
concat()
返回一个由两个数组组成的新数组,而
push()
向当前数组添加一个元素。这就是为什么
push()

回答相应的问题:

if (pairs[0] === pairs[1] && pairs.length!== 0){
  console.log('MATCH')
} else if(pairs.length === 2){
    this.setState(prevState => ({ cardPairs: [] }))
}
你的逻辑有错误。基本上,您连接新的pair值并将其提交到您的状态(通过
this.setState({cardPairs:pairs.concat(e.target.value})
)。但是,如果
条件依赖于
e.target.value
,那么
pairs
变量就过时了

此外,从代码角度看,您严格地只比较数组的前两个元素,这导致了无限不匹配问题

解决方案 我们可以采取另一种方法:首先,每当单击一个新的、唯一的值时,将其添加到数组中。但是,如果我们遇到一个已经在数组中的值,那么这意味着我们有一个匹配项。然后我们可以过滤掉该元素(可能还有一个删除函数也可以很好地工作)。这意味着我们的配对将始终只包含唯一值,并且在存在匹配项时将删除唯一值

const pairs = this.state.cardPairs.slice();
if (pairs.includes(e.target.value)) {
  console.log("Match");
  this.setState({ cardPairs: pairs.filter(el => el != e.target.value )})
} else {
  // Otherwise, add more elements to the list.
  this.setState({ cardPairs: pairs.concat(e.target.value) });
}
用户单击1: [1]

用户再次单击1: []

用户单击0,1: [0,1]

用户单击1: [0]


沙盒:

我已经这么做了,仍然需要单击三下才能找到匹配constpairs=this.state.cardPairs.slice()您好,我刚刚更新了答案。在您的if条件中,您使用的是旧数组,但新数组没有连接到它。我按照您所说的做了,仍然单击了三次…抱歉,请重新检查代码。我向您发送了错误代码,但现在应该可以工作了。这里还有一个实例。基本上,我为您提供了错误的代码来使用this.setState回调。要使用新状态,只需调用this.state.cardPairs。但是,我认为我没有正确回答问题(用于删除匹配的元素)。是否要匹配数组中的任何重复项?如用户单击0->0,则匹配。但如果用户单击0->1->0,则同时删除两个0?如果是,我们将不得不更改答案,使其不依赖数组的前两个元素。。