sync$()
Синхронные события (BETA)
Qwik обрабатывает события асинхронно. Это означает, что некоторые API, такие как event.preventDefault()
и event.stopPropagation()
, не работают так, как ожидается. Чтобы обойти это ограничение, Qwik предоставляет API sync$()
, который позволяет обрабатывать события синхронно. Но sync$()
имеет несколько оговорок:
sync$()
не может закрыть ни одно состояние.sync$()
не может вызывать другие функции, которые объявлены в области видимости или импортированы.sync$()
сериализуется в HTML, и поэтому мы должны помнить о размере функции.
Типичный способ справиться с этими ограничениями - разделить обработку событий на две части:
sync$()
, которая вызывается синхронно и может вызывать такие методы, какevent.preventDefault()
иevent.stopPropagation()
.$()
, которая вызывается асинхронно и может закрывать состояние и вызывать другие функции, а также не имеет ограничений на размер.
Поскольку sync$()
не может получить доступ к состоянию, какова наилучшая стратегия работы с ним? Ответ заключается в использовании атрибутов элементов для передачи состояния в функцию sync$()
.
sync$()
с состоянием
Пример: В этом примере мы хотим предотвратить поведение ссылки по умолчанию на основе некоторого состояния. Для этого мы разбиваем код на три части:
sync$()
: синхронная часть, которая сведена к минимуму,$()
: асинхронная часть, которая может быть произвольно большой и может закрываться по состоянию,data-should-prevent-default
: атрибут элемента, который используется для передачи состояния в функциюsync$()
.
import { component$, useSignal, sync$, $ } from '@builder.io/qwik';
export default component$(() => {
const shouldPreventDefault = useSignal(true);
return (
<div>
<div>Событие синхронизации:</div>
<input
type="checkbox"
checked={shouldPreventDefault.value}
onChange$={(e, target) =>
(shouldPreventDefault.value = target.checked)
}
/>{' '}
Должны предотвратить по умолчанию
<hr />
<a
href="https://google.com"
target="_blank"
data-should-prevent-default={shouldPreventDefault.value}
onClick$={[
sync$((e: MouseEvent, target: HTMLAnchorElement) => {
if (target.hasAttribute('data-should-prevent-default')) {
e.preventDefault();
}
}),
$(() => {
console.log(
shouldPreventDefault.value ? 'Предотвращено' : 'Не предотвращено'
);
}),
]}
>
открыть Google
</a>
</div>
);
});