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