React useState传入关联翻转状态的数组后翻牌功能失效如何解决
问题根因
- 你把
isFlipped状态的引用写死在cardsInit里,而useState的初始值仅会在组件首次渲染时计算一次,后续isFlipped更新时,cards状态里存储的isCard值不会同步更新,因此翻牌逻辑失效 - 同时维护两个独立状态
isFlipped和cards会导致状态同步冲突,完全没有必要分开维护 - 注释掉的移除卡片代码用了错误的
slice用法,且存在定时器闭包问题,会导致移除逻辑异常
解决方案
直接将翻转状态合并到cards的单条卡片数据中,仅维护cards一个状态即可,修改后完整代码如下:
import { useState } from 'react' import ReactCardFlip from 'react-card-flip' const CardsComp = () => { // 初始卡片数组,直接把翻转状态存在单条卡片数据里 const initCards = [ { id: '1', cardName: 'Cat Card', isFlipped: false }, { id: '2', cardName: 'Defuse card', isFlipped: false }, { id: '3', cardName: 'Shuffle card', isFlipped: false }, { id: '4', cardName: 'Exploding kitten', isFlipped: false }, ] const [cards, setCards] = useState(initCards) // 点击翻牌+3秒后移除逻辑 const handleFlip = (cardId) => { // 先更新翻牌状态 setCards(prev => prev.map(card => { if (card.id === cardId) { return {...card, isFlipped: !card.isFlipped} } return card })) // 3秒后移除当前点击的卡片 setTimeout(() => { setCards(prev => prev.filter(card => card.id !== cardId)) }, 3000) } return ( <div> {cards.map((card) => ( <ReactCardFlip key={card.id} isFlipped={card.isFlipped} flipDirection="vertical" > {/* 牌正面 */} <div className="front"> Choose Me! <button className="bg-red-500 p-2" onClick={() => handleFlip(card.id)} > Open </button> </div> {/* 牌背面 */} <div className="back"> {card.cardName} <button className="bg-red-500 p-2" onClick={() => handleFlip(card.id)} > Open </button> </div> </ReactCardFlip> ))} </div> ) } export default CardsComp
修改说明
- 删掉了冗余的
isFlipped独立状态,把翻转状态合并到单张卡片数据中,避免状态不同步问题 - 点击逻辑统一放在
handleFlip函数中,先触发翻牌,再开定时器3秒后移除对应卡片 - 所有状态更新都用了函数式更新写法,避免定时器闭包导致的状态获取异常
- 移除卡片用
filter方法实现,逻辑更清晰不易出错
内容的提问来源于stack exchange,提问作者Akhil Rana
相关产品推荐
相关产品推荐

