Зачем мне setTimeout для обновления состояния в компоненте React - PullRequest
0 голосов
/ 02 марта 2020

Зачем мне оборачивать мое setValue с помощью setTimeout в моем компоненте React?

Это работает

<Button onClick={() => acceptOne()}>
  set value with setTimeout
</Button>

const acceptOne = () => {
  setTimeout(() => {
    setEditMode(false);
  });
};

Это не ...

<Button onClick={() => acceptTwo()}>
  set value without setTimeout
</Button>

const acceptTwo = () => {
  setEditMode(false);
};

Вот пример CodeSandbox для полного кода, чтобы продемонстрировать проблему.

Я новичок в React и уже должен был использовать setTimout, чтобы получить состояние для изменения, как это. Я чувствую, что это скорее всего новичок, и есть некоторые React-специфические вещи, которые я еще не понимаю. Что здесь происходит, почему setValue не работает, когда я не использую setTimeout?

Ответы [ 4 ]

2 голосов
/ 02 марта 2020

Это происходит из-за распространения события. Как вы можете видеть, вы связали событие с родительским div. Таким образом, всякий раз, когда вы нажимаете на кнопке, событие родительского div также выполняется .

Почему он работает с setTimeout?

Поскольку он выполняется после события div, потому что он был передан другому асинхронному c процессу и требуется время, чтобы выполнить.

Вы можете добавить event.stopPropagation(), чтобы остановить всплывающее событие в DOM:

  const acceptOne = e => {
    e.stopPropagation();
    setEditMode(!editMode);
  };

  const acceptTwo = e => {
    e.stopPropagation();
    setEditMode(!editMode);
  };

Теперь измените событие на:

onClick={acceptOne}
onClick={acceptTwo}

или:

onClick={e => acceptOne(e)}
onClick={e => acceptTwo(e)}  

Обновлены коды и поле

0 голосов
/ 02 марта 2020

https://codesandbox.io/s/charming-ganguly-mg4zx Я исправил, ссылка есть. Так что это из-за того, что после второго щелчка на входе он запускает родительский элемент div тоже, потому что этот вход обернут в элемент div, <div onClick={() => setEditMode(!editMode)}> Так что, когда вы помещаете туда setTimeout, второй щелчок ввода запускается перед функцией щелчка родительского элемента div. Вот почему это работает. Это конкретно связано с событием javascript l oop, посмотрите видео о событии l oop и вы поймете, что там происходит https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=54s

0 голосов
/ 02 марта 2020
  <div onClick={() => setEditMode(true)}>

это ваша проблема. Родительский DIV, который оборачивает ваше событие кнопок, вызывается так же, как нажатие вашей кнопки. Задержка, которую обеспечивает setTimeout, позволяет ему войти после родительского div и, следовательно, работает. Вы можете либо реструктурировать свой HTML, либо выполнить какое-либо событие stopPropogation для его обработки.

0 голосов
/ 02 марта 2020

Проблема с верхней строкой в ​​вашем коде <div onClick={() => setEditMode(true)}>

Просмотрите обновленный фрагмент - https://codesandbox.io/s/charming-http-b637o

Logi c очень хорошо объясняется Джай в своем ответе.

...