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>
);
});