UseState не обновляет значение

Я пытаюсь обновить значение с помощью useState, но оно не обновляет значение

Вот мой код:

В этом коде, когда я нажимаю на элемент div, он показывает детали, но когда я нажимаю кнопку скрытия, он не скрывает детали.

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
}

🤔 А знаете ли вы, что...
React Router - это библиотека для управления маршрутизацией в приложениях React.


333
1

Ответ:

Решено

Трудно сказать, не видя всего представления компонента, но проблема может заключаться в структуре вашего HTML-кода.

Если кнопка, которая вызывает метод скрытия, находится внутри div, который ее показывает, скорее всего, источником проблемы является распространение события. Предположим, что ваше представление имеет такую ​​структуру:

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

Нет ничего плохого в том, как вы звоните setState как таковом, но когда вы нажимаете на кнопку, происходят две вещи:

  1. Метод hideDetails вызывается при нажатии кнопки, поэтому show устанавливается на false.

  2. Событие щелчка распространяется на родительские элементы, и, поскольку кнопка находится внутри div, это приводит к тому, что showDetails запускается снова, а show возвращается к true.

Этот последний шаг объясняет, почему ваш элемент продолжает отображаться даже после нажатия кнопки. Решение для этого состоит в том, чтобы остановить распространение события в методе hideDetails, например:

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

Остановка распространения гарантирует, что будет работать только обработчик события нажатия кнопки, поэтому showDetails больше не будет выполняться при нажатии кнопки.

Полный рабочий пример приведен ниже:

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>