React реализует собственную систему событий, чтобы обеспечить поддержку кроссбраузерной совместимости. По сути, React оборачивает собственное событие браузера в экземпляр React SyntheticEvent и передает его в обработчики событий React. SyntheticEvent имеет тот же интерфейс, что и собственное событие, что означает, что вы можете использовать такие методы, как preventDefault() и stopPropagation().

Как React управляет системой событий?

По соображениям производительности React повторно использует SyntheticEvent объекты, объединяя их. Это означает, что объект SyntheticEvent используется повторно, поэтому после вызова обработчика события все свойства на event.target обнуляются.

«Предупреждение: это синтетическое событие используется повторно из соображений производительности»

Это предупреждение появляется, когда мы пытаемся получить доступ к синтетическому событию React асинхронным способом. Из-за повторного использования после вызова обратного вызова события синтетический объект события больше не будет существовать, поэтому мы не сможем получить доступ к его свойствам.

Самый распространенный пример асинхронного доступа к SyntheticEvent - внутри setState. Когда мы обновляем состояние компонента с помощью функции обновления, средство обновления будет вызываться асинхронно, и событие уже будет аннулировано.

Решение 1: event.persist()

Вызов event.persist() синтетического события удаляет событие из пула, позволяя асинхронно сохранять ссылки на событие.

Решение 2.Кэшируйте необходимые свойства

Мы можем сохранить свойства события в обработчике событий и передать их асинхронному обратному вызову вместо доступа к событию непосредственно из асинхронного обратного вызова:

Отказ от синтетического обработчика событий.

Другой распространенный пример, помимо setState, - это обратный вызов с отклонением:

Метод debounce из lodash создает функцию, которая будет вызываться асинхронно, поэтому, если мы попытаемся получить доступ к объекту напрямую из обратного обратного вызова, синтетическое событие будет уже обнулено.

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

Подводя итоги

React оборачивает собственные события браузера в экземпляры SyntheticEvent. К синтетическому событию нельзя получить доступ асинхронно, потому что React повторно использует его после вызова обработчика. В качестве возможных решений мы можем вызвать event.persist() или кэшировать необходимые свойства события до тех пор, пока они не будут окончательно использованы.