首页 > 解决方案 > 在使用顺风的同时在 reactjs 中添加样式

问题描述

我想在用户单击按钮时为元素设置动画。该元素显示按钮被点击的次数。这是通过每次单击按钮时递增的状态来管理的。

每当单击按钮时,显示的数字应弹跳/动画,以强调其变化。

本质上,我想有条件地附加一个 CSS 类。有很多关于如何做到这一点的例子,但几乎所有的例子都只应用了一个类,而不是很多类。

我使用tailwindcss进行造型。这意味着大量元素上的大量 CSS 类。

我所考虑的

字符串连接

有一个classNames数组,可以轻松添加和删除动画类。

const [count, setCount] = useState(0);
const [classNames, setClassNames] = useState([
    'text-2xl', 'mb-2', 'font-bold', 'text-black', 'dark:text-white'
]);

const countElement = <p className={classNames.join(' ')}>{count}</p>;

const handleClick = () => {
    
    setCount(count + 1);
    
    // Append the animation class.
    setClassNames(classNames.concat('animate-bounce'));

    // Remove the animation class after the animation is done.
    setTimeout(() => {
        setClassNames(classNames.filter(className => 
            className !== 'animate-bounce'));
    }, 1000);
};

return <>
    {count > 0 ? countElement : null}
    <button className="px-4 py-3 mb-2 rounded-lg font-semibold transition-colors duration-300
                       bg-cardinal-default hover:bg-cardinal-dark active:bg-cardinal-darkest
                       text-black dark:text-white" 
                       onClick={handleClick}>Click me</button>
</>;

虽然使用 tailwindcss 这有点难看,因为它将所有样式与其实际元素分开。不完全理想。感觉非常hacky。

动画内部元素

    const [isBouncing, setIsBouncing] = useState(false);

    const countElement = (
        <p className="text-2xl mb-2 font-bold text-black dark:text-white">
            <span className={isBouncing ? 'inline-block animate-spin' : ''}>{count}</span>
        </p>
    );

    ...
    
        setCount(count + 1);
        setIsBouncing(true);

        setTimeout(() => setIsBouncing(false), 1000);
    
    ... 
    

这更好,但它仍然需要我设置inline-block

有没有更好的方法来做到这一点?还是我已经用尽了所有有价值的解决方案?

标签: javascriptreactjstailwind-css

解决方案


您可以使用像styled-components这样的 css-in-js 解决方案,这将使启用/禁用样式变得非常容易。

对于顺风有一个库来帮助 css-in-js 称为twin

这允许您有条件地启用样式:

const Button = styled.button`
  ${tw`your tailwind styles here`}
  ${props => props.shouldAnimate ? `some animation css here` : "" }
`

推荐阅读