Quiero animar un elemento cuando el usuario hace clic en un botón. El elemento muestra un recuento de cuántas veces se ha hecho clic en el botón. Esto se gestiona a través de un estado que se incrementa con cada clic de botón.
Cada vez que se hace clic en el botón, el número mostrado debe rebotar/animarse para enfatizar su cambio.
En esencia, quiero agregar condicionalmente una clase CSS. Hay muchos ejemplos de cómo hacer esto, pero casi todos ellos solo tienen una sola clase aplicada, no muchas clases.
Uso tailwindcss para diseñar. Esto significa muchas clases de CSS en muchos elementos.
Tener una matriz classNames , donde la clase de animación se puede agregar y eliminar fácilmente.
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> </>;Aunque con tailwindcss esto es un poco feo ya que separa todo el estilo de su elemento real . No es exactamente ideal. Se siente muy 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); ... Esto es mejor, pero aún requiere que configure inline-block
¿Hay una mejor manera de hacer esto? ¿O he agotado todas las soluciones que valen la pena?
Podría usar una solución css-in-js como componentes con estilo que hará que sea muy fácil habilitar/deshabilitar estilos.
Para el viento de cola, hay una biblioteca para ayudar con css-in-js llamada twin
Esto le permite habilitar estilos condicionalmente:
const Button = styled.button` ${tw`your tailwind styles here`} ${props => props.shouldAnimate ? `some animation css here` : "" } `TailwindCSS es un marco CSS de primera utilidad, por lo que probablemente no haya otra opción que agregar clases a sus elementos.
Si tuviera que usar una biblioteca de animación, como Framer Motion, no sería necesario agregar clases de Tailwind. Por otro lado, necesitaría crear la animación usted mismo, lo cual es bastante fácil.
Con respecto a sus consideraciones, la primera alternativa parece muy complicada, mientras que la segunda no lo hace y debería funcionar también.
No obstante, depende de usted decidir qué método le conviene más.