0

I am building a Next.js App with React.


    const partyButton = useRef(null)
    const handleParty = () => {
        setTimeout(() => {
        partyButton.current.classList.add('party-time');
        console.log(partyButton.current.classList)
        }, 10);
    }

    return (
        <div className={styles.main_div}>
            <button className={styles.button_2} ref={partyButton} onClick={handleParty}>click for party</button>
        </div>
    )
} 
.party-time {
    animation: party 2000ms infinite;
}

@keyframes party {
    0% {
        background: red;
    }
    20% {
        background: orangered;
    }
    40% {
        background: orange;
    }
    60% {
        background: red;
    }
    80% {
        background: orangered;
    }
    100% {
        background: orange;
    }
} 

The classList shows there is the animation in the classList. Nothing happens though. Looks like: DOMTokenList(2) ['cssanimation_button_2__iAS4j', 'party-time', value: 'cssanimation_button_2__iAS4j party-time']

isherwood
  • 58,414
  • 16
  • 114
  • 157
marian
  • 27
  • 7
  • 3
    That's not the right way to manipulate classes in React. You should have [conditional classes](https://stackoverflow.com/questions/30533171/react-js-conditionally-applying-class-attributes) and update a property of your component to enable them. You should rarely be directly manipulating elements in React. – isherwood Apr 25 '23 at 18:37
  • 2
    Protip: Never use the word "click" to direct your users. They know how buttons work. Instead, tell them what the button click will _do_. `[ Join the party ]` – isherwood Apr 25 '23 at 18:38
  • Hm i dont think my question was very concise. I mostly wondered how to accomplish this css-animation with an onClick-method but i suppose that i could add a css property to it. Great advice! – marian Apr 26 '23 at 07:20
  • I understand your advice, it is just not what i was asking. I do now add the class like this: ` ` `
    ` and i can still confirm that "party-time" or "dot-dance" is being added, but it does not play the animation.
    – marian Apr 26 '23 at 16:25
  • 1
    If your question is just about CSS, simplify your question to just show HTML and CSS (and maybe a timeout function). Don't complicate and distract with React code. – isherwood Apr 26 '23 at 16:33
  • 1
    @marian You are using `styles.dots` for one class and `"dot-dance"` for another. Are you sure, that "dot-dance" is actually the name of the class after compiling? It seems like you are using CSS Modules --- in that case, rename the class to `.dotDance` and set it with `styles.dotDance` – Lars Munkholm Apr 26 '23 at 21:25

1 Answers1

2

Never set or change the classList, like you are doing in your example, when coding React.

Instead you should use a state:

    const [animate, setAnimate] = useState(false);
    const handleParty = () => {
       setAnimate(true);
    }

    return (
        <div className={styles.main_div}>
            <button className={[styles.button_2, animate && "party-time"].join(" ")} onClick={handleParty}>click for party</button>
        </div>
    )

Many use the classnames or clsx packages for handling classNames.

If your class "party-time" set using some kind of CSS-in-JS or CSS Modules, you might need to rename it to party_time or partyTime, and set it with styles.partyTime instead of "party-time"

Lars Munkholm
  • 190
  • 1
  • 9