React中两次调用shuffle函数返回相同结果的问题求助
问题分析与解决方案
你的问题根源在于**shuffle函数原地修改数组并返回原引用**,导致两次调用实际上操作的是同一个数组对象,最终cards1和cards2指向的是同一个结果。
具体原因
看你的shuffle函数:
export const shuffle=(a)=> { for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; }
它直接修改了传入的数组a,然后返回同一个数组的引用。当你执行:
const cards1=shuffle(cards) const cards2=shuffle(cards)
第一次调用已经把cards数组打乱,第二次调用是在这个已经打乱的数组上再次打乱,而且cards1和cards2都是指向cards这个同一个数组,所以最终两者的结果完全一致。
两种解决方案
方案1:修改shuffle函数,操作数组副本
让shuffle函数先创建原数组的浅拷贝,再对副本进行打乱,这样每次调用都会返回一个全新的数组,不会影响原数组和其他调用结果:
export const shuffle=(a)=> { // 创建原数组的浅拷贝,避免修改原数组 const arr = [...a]; for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } return arr; }
方案2:调用shuffle时传入数组副本
如果你不想修改shuffle函数,可以在每次调用时传入原数组的副本,保证两次打乱操作的是独立的数组:
shuffleCards=()=>{ const cards=this.props.selectedCards // 每次调用shuffle都传入新的数组副本 const cards1=shuffle([...cards]) const cards2=shuffle([...cards]) this.setState({cards1, cards2}) const id1=cards1.map(c=>c.id) const id2=cards2.map(c=>c.id) console.log(id1, id2) }
补充说明
如果你的selectedCards中的元素是复杂对象,[...cards]这种浅拷贝已经足够满足打乱顺序的需求(因为你只是调整元素的位置,不会修改对象内部的属性)。如果需要深拷贝对象,可以使用JSON.parse(JSON.stringify(a))或者第三方库,但在这个场景下浅拷贝完全够用。
内容的提问来源于stack exchange,提问作者Nhat
相关产品推荐
相关产品推荐

