0

I am trying to update the value using useState but it does not updating the value

Here is my code:

In this code when i am click on item div it shows details but when i am click on hide button it doesn't hide details.

const [show, setShow] = useState(false);

function showDetails() {
   setShow(true);
}

function hideDetails() {
   setShow(false);
}

<div className="item" onClick={showDetails}>  
   some code...
</div>

{show
  ? <div className="details-container">
    some code...
    <button onClick={hideDetails}>Hide</button>
    </div>
  : null
}
0

1 Answer 1

4

It's hard to say without seeing the whole component's view, but the problem may lie in the structure of your HTML code.

If the button that calls the hide method is inside of the div that shows it, event propagation is likely to be the source of the problem. Let's assume that your view has a structure like this:

<div className="item" onClick={showDetails}>
  {show ? (
    <div className="details-container">
      <button onClick={hideDetails}>Hide</button>
    </div>
  ) : null}
</div>

There's nothing wrong with the way you're calling setState per se, but when you click on the button two things happen:

  1. The hideDetails method is called when the button is clicked, so show is set to false.

  2. The click event is propagated to the parent elements and, since the button is inside of the div, this causes the showDetails to run again and show is set back to true.

This last step explains why your element keeps showing even after the button has been clicked. The solution for this is to stop event propagation on the hideDetails method, like this:

function hideDetails(e) {
  e.stopPropagation();
  setShow(false);
}

Stopping propagation will ensure that only the click event handler of the button runs, so showDetails will no longer be executed when the button is clicked.

The full working example is listed below:

const App = () => {
  const [show, setShow] = React.useState(false);

  const showDetails = () => {
    setShow(true);
  };

  const hideDetails = (e) => {
    e.stopPropagation();
    setShow(false);
  };

  return (
    <div className="item" onClick={showDetails}>
      <b>Item</b>
      {show ? (
        <div className="details-container">
          <p>Details</p>
          <button onClick={hideDetails}>Hide</button>
        </div>
      ) : null}
    </div>
  );
};

ReactDOM.render(
  <App />,
  document.getElementById("react")
);
.item {
  padding: 1em;
  background: #CCCCCC;
  border: black solid 1px;
}

.details-container {
  padding: 1em;
  background: #EEEEEE;
  border: black solid 1px;
}

p {
  margin: 0 0 .5em 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="react"></div>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! @LonelyPrincess this code is working fine

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.