sync$() 同步事件 (測試版)

Qwik 以非同步方式處理事件。這表示某些 API,例如 event.preventDefault()event.stopPropagation() 不會如預期般運作。為了克服這個限制,Qwik 提供了一個 sync$() API,允許您同步處理事件。但 sync$() 有一些注意事項

  1. sync$() 無法封閉任何狀態。
  2. sync$() 無法呼叫在範圍內宣告或導入的其他函數。
  3. sync$() 會被序列化到 HTML 中,因此我們應該注意這個函式的體積大小。

處理這些限制的典型方法是將事件處理拆分為兩個部分:

  1. sync$():同步呼叫,可以呼叫 event.preventDefault()event.stopPropagation() 等方法。
  2. $():非同步呼叫,可以封閉狀態並呼叫其他函式,並且沒有大小限制。

由於 sync$() 無法存取狀態,處理它的最佳策略是什麼?答案是使用元素屬性將狀態傳遞給 sync$() 函式。

注意:如果只需要阻止預設行為,可以使用標準的 preventDefault:{eventName} 語法。這嚴格適用於需要同步鏈接事件的情況。

範例:具有狀態的 sync$()

在此範例中,我們有一個行為,我們想要根據某些狀態來阻止連結的預設行為。我們透過將程式碼分成三個部分來做到這一點:

  1. sync$():保持在最小值的同步部分。
  2. $():可以任意大的非同步部分,並且可以封閉狀態。
  3. data-should-prevent-default:元素上的一個屬性,用於將狀態傳遞給 sync$() 函式。
import { component$, useSignal, sync$, $ } from '@builder.io/qwik';
 
export default component$(() => {
  const shouldPreventDefault = useSignal(true);
  return (
    <div>
      <div>Sync Event:</div>
      <input
        type="checkbox"
        checked={shouldPreventDefault.value}
        onChange$={(e, target) =>
          (shouldPreventDefault.value = target.checked)
        }
      />{' '}
      Should Prevent Default
      <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 ? 'Prevented' : 'Not Prevented'
            );
          }),
        ]}
      >
        open Google
      </a>
    </div>
  );
});

貢獻者

感謝所有讓這份文件變得更好的貢獻者!

  • mhevery
  • RumNCodeDev