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

如何将React useState状态传入结合Tailwind、twin.macro的Styled Components切换类

方案1:在Styled Component内部根据prop动态切换Tailwind类(符合你预期的实现方式)

这是最贴合你需求的写法,修改后完整可运行代码如下:

import { useState } from 'react';
import tw, { styled } from 'twin.macro';

export default function Header() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <Wrapper>
      <ButtonWrap type="button" onClick={() => setIsOpen(!isOpen)}>
        My Button
      </ButtonWrap>
      {/* 将isOpen状态作为prop传给StyledDiv */}
      <StyledDiv isOpen={isOpen}>
        要控制显隐的内容
      </StyledDiv>
    </Wrapper>
  )
}

const Wrapper = styled.div`
  ${tw`container shadow`}
`

const ButtonWrap = styled.button`
  ${tw`block text-mycolor hover:text-myothercolor focus:text-myothercolor`}
`

// 定义接收isOpen参数,动态返回对应的Tailwind类
const StyledDiv = styled.div<{ isOpen: boolean }>`
  /* 先写固定的公共样式 */
  ${tw`px-2 pt-2 pb-4`}
  /* 根据prop值切换显隐类 */
  ${({ isOpen }) => isOpen ? tw`block` : tw`hidden`}

错误原因说明

你之前的写法存在两个问题:

  • 混淆了原生CSS属性值和Tailwind类:原生CSS的display属性不存在hidden取值,hidden是Tailwind封装的对应display: none的工具类,不能直接写在原生CSS属性后面。
  • Styled组件无法直接读取上层组件的状态,必须通过prop传递才能在组件内部拿到状态值做判断。

方案2:JSX层直接拼接类名(更贴近Vue的:class写法)

如果你不想修改Styled组件的定义,也可以直接在调用层动态拼接Tailwind类,逻辑和Vue的动态类绑定完全一致:

export default function Header() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <Wrapper>
      <ButtonWrap type="button" onClick={() => setIsOpen(!isOpen)}>
        My Button
      </ButtonWrap>
      {/* 直接拼接动态类,不需要额外定义Styled组件 */}
      <div className={`px-2 pt-2 pb-4 ${isOpen ? 'block' : 'hidden'}`}>
        要控制显隐的内容
      </div>
    </Wrapper>
  )
}

内容的提问来源于stack exchange,提问作者Stephen Parker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:30:01