在 React 中切换翻转卡片

Toggle flip cards in React

我正在尝试创建翻转卡片效果,如果我点击一张卡片,它就会翻转过来。但是,如果我随后单击另一张卡片,我希望将原来的卡片翻转回来。这意味着在所有卡片上都有某种全局切换,但被本地切换覆盖的卡片除外。我不确定最 React-y 的方式来做到这一点 - 我已经尝试在两个级别上使用 useState 挂钩实现它,但我没有太多运气。

我正在使用样式化组件,'flipped' 属性决定了 Y 变换。

这是翻页卡片组件,您可以看到我到目前为止的尝试:

const PortfolioItem = props => {
  const [flipped, setFlipped] = useState(false)

  return (
    <PortfolioItemStyles onClick={() => setFlipped(!flipped)}>

// what I'm trying to say here is, if the individual card's 'flipped' is set to true, 
use that, otherwise use props.flipped which will be set to false

      <PortfolioItemInnerStyle flipped={flipped ? flipped : props.flipped}>
        <PortfolioItemFront >
          {props.image}
          <PortfolioImageCover className="img-cover" />
          <PortfolioItemHeader>{props.title}</PortfolioItemHeader>
        </PortfolioItemFront>
        <PortfolioItemBack>
            <h1>Hello there</h1>
        </PortfolioItemBack>
      </PortfolioItemInnerStyle>
    </PortfolioItemStyles>
  )
}

function PortfolioStyles() {
    const [ allFlipped, setAllFlipped ] = useState(false);

  return (
    <PortfolioContainer>
      {portfolioItems.map(item => {
        return <PortfolioItem image={item.image} flipped={allFlipped} title={item.title} onClick={() => setAllFlipped(false)} />
      })}
    </PortfolioContainer>
  )
}

我使用的逻辑显然是错误的,但我想知道 'best practice' 这样做的方法是什么?在 vanilla JS 中,您将使用单个事件处理程序并在其上使用 event.target 以确保您隔离了元素,但我不确定如何在 React 中处理它。任何帮助将不胜感激。

我个人只会管理容器组件上的状态。假设您将存储翻转卡片的索引而不是 true/false 状态。然后 onClick 将更改当前索引,并通过检查 index === currentIndex 计算翻转。像这样:

const PortfolioItem = props => {

  return (
    <PortfolioItemStyles>
      <PortfolioItemInnerStyle flipped={props.flipped}>
        <PortfolioItemFront >
          {props.image}
          <PortfolioImageCover className="img-cover" />
          <PortfolioItemHeader>{props.title}</PortfolioItemHeader>
        </PortfolioItemFront>
        <PortfolioItemBack>
            <h1>Hello there</h1>
        </PortfolioItemBack>
      </PortfolioItemInnerStyle>
    </PortfolioItemStyles>
  )
}

function PortfolioStyles() {
    const [ currentFlippedIndex, setCurrentFlippedIndex ] = useState(-1);

  return (
    <PortfolioContainer>
      {portfolioItems.map((item, index) => {
        return <PortfolioItem image={item.image} flipped={index === currentFlippedIndex} title={item.title} onClick={() => setCurrentFlippedIndex(index)} />
      })}
    </PortfolioContainer>
  )
}