0

I have a button that shows/hides an element when click but it does not work on first click but it works on the following clicks. I'm expecting it to work on the first click.

import { useState } from "react";

function myComponent() {

    const [elem, setElem] = useState(false);
    const handleClick = () => {
        setElem(true);
        if(elem) {
            document.getElementById('item').classList.toggle('show');
            document.getElementById('item').classList.toggle('hide');
        }
    }

    return (
        <button onClick={handleClick}>touch me</button>
    );
}

export default Navbar;

What I imagine that is happening under the hood is that when the button is clicked it will set the elem to 'true' then the 'if' statement runs because the elem is 'true'. I also tried to console.log the elem outside and inside the if statement and it shows false and the if statement doesn't run on the first click. I could just remove the if statement and not use a State but I want to do other things if the button is clicked. Can someone explain to me what really is happening here under the hood? Thank you!

1
  • 1
    setElem() does not immediately mutate elem but creates a pending state transition. Accessing ''elem`` after calling this method can potentially return the existing value. Commented Aug 20, 2024 at 17:16

2 Answers 2

1

setElem() does not immediately mutate elem but creates a pending state transition. Accessing elem after calling this method can potentially return the existing value.

You can use useEffect hook.

import { useState, useEffect } from "react";
    
    function myComponent() {
    
        const [elem, setElem] = useState(false);
        const handleClick = () => {
            setElem(true);
           
        }
    
    useEffect(()=>{
     if(elem) {
             document.getElementById('item').classList.toggle('show');
             document.getElementById('item').classList.toggle('hide');
     }
    },[elem])
    
        return (
            <button onClick={handleClick}>touch me</button>
        );
    }
    
    export default Navbar;
Sign up to request clarification or add additional context in comments.

Comments

0

setState calls in React are asynchronous. That means that after you call setElem(true), elem hasn't updated yet when the if statement runs and is therefore still false.

Instead, you can set the state after you run the if statement like so:

const handleClick = () => {
    if(!elem) {
        document.getElementById('item').classList.toggle('show');
        document.getElementById('item').classList.toggle('hide');
    }
    setElem(true);
}

Alternatively, you could use setElem with a callback or the useEffect hook.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.