You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 00:36:00