title: Appending styling in reactjs whilst using tailwind
body: <p>I want to animate an element when the user clicks on a button.
  The element displays a count of how many times the button has been clicked. This is managed through a state that is incremented on every button click.</p>
  <p>Whenever the button is clicked, the displayed number should bounce/animate, to emphasize its change.</p>
  <p>In essence I want to conditionally append a CSS class. There's many examples of how to do this, but almost all of them only have a single class applied to them, not lots of classes.</p>
  <p><strong>I use <a href="https://tailwindcss.com/" rel="nofollow noreferrer">tailwindcss</a> for styling.</strong> This means lots of CSS classes on lots of elements.</p>
  <h1>What I have considered</h1>
  <h2>String concatenation</h2>
  <p>Having a <code>classNames</code> array, where the animation class can be added and removed easily.</p>
  <pre class="lang-js prettyprint-override"><code>const [count, setCount] = useState(0);
  const [classNames, setClassNames] = useState([
      'text-2xl', 'mb-2', 'font-bold', 'text-black', 'dark:text-white'
  ]);
  
  const countElement = &lt;p className={classNames.join(' ')}&gt;{count}&lt;/p&gt;;
  
  const handleClick = () =&gt; {
      
      setCount(count + 1);
      
      // Append the animation class.
      setClassNames(classNames.concat('animate-bounce'));
  
      // Remove the animation class after the animation is done.
      setTimeout(() =&gt; {
          setClassNames(classNames.filter(className =&gt; 
              className !== 'animate-bounce'));
      }, 1000);
  };
  
  return &lt;&gt;
      {count &gt; 0 ? countElement : null}
      &lt;button className=&quot;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&quot; 
                         onClick={handleClick}&gt;Click me&lt;/button&gt;
  &lt;/&gt;;
  </code></pre>
  <p>Though with tailwindcss this is kind of ugly as <strong>it separates all of the styling from its actual element</strong>. Not exactly ideal. It feels very hacky.</p>
  <h2>Animate an inner element</h2>
  <pre><code>    const [isBouncing, setIsBouncing] = useState(false);
  
      const countElement = (
          &lt;p className=&quot;text-2xl mb-2 font-bold text-black dark:text-white&quot;&gt;
              &lt;span className={isBouncing ? 'inline-block animate-spin' : ''}&gt;{count}&lt;/span&gt;
          &lt;/p&gt;
      );
  
      ...
      
          setCount(count + 1);
          setIsBouncing(true);
  
          setTimeout(() =&gt; setIsBouncing(false), 1000);
      
      ... 
      
  </code></pre>
  <p>This is better, yet it still requires me to set <code>inline-block</code></p>
  <p><strong>Is there a better way of doing this? Or have I exhausted all worthwhile solutions?</strong></p>