傳遞閉包

屬性必須是可序列化的,以便 Qwik 可以獨立於頁面上的其他元件恢復和呈現每個元件。如果我們希望將回調函數傳遞給子元件,這就會造成問題。回調函數是函數,而函數不能直接序列化,但它們可以通过將其先轉換為 QRL 來序列化。

QRLs

跨可序列化邊界傳遞的函數必須通過 QRL 完成。QRL 是函數的序列化形式。(請參閱進階章節中的QRL。)

Qwik 有一些以 $ 結尾的便捷 API - 這些 API 等同於直接調用 $()。以下兩行是等效的

  • 內嵌:useTask$(() => {...}/>
  • 顯式:const callbackQrl = $(() => {...}); useTaskQrl(callbackQrl)

大多數情況下,我們使用第一種形式,因為它允許我們將回調函數直接內嵌到 API 中。但有時需要使用第二種形式,以便我們可以將函數聲明的位置与其使用的位置分開。

聲明回調函數屬性

元件可以通过以下方式在其屬性中聲明回調函數:

  • $ 結尾的屬性(如 goodbye$
  • 屬性的類型為 QRL<T>,其中 T 是 QRL 指向的惰性引用類型(函數簽名)。
interface MyComponentProps {
  goodbye$: QRL<() => void>;
  hello$: QRL<() => void>;
}
 
export const MyComponent = component$((props: MyComponentProps) => { ... });

這允許 <MyComponent> 的使用者使用如下所示的 goodbye$ 形式

<MyComponent goodbye$={goodbyeQrl} hello$={() => {...}} />

使用回調函數屬性

請注意,<MyComponent> 元件接收一個回調函數。

props.goodbye$ 作為引用傳遞給 <button>

<button onClick$={props.goodbye$}>good bye</button>

<button> 建立新的回呼並在內部呼叫回呼 QRL。

<button
  onClick$={async () => {
    await props.hello$?.invoke('World');
  }}
>
  hello
</button>

這個形式允許 <button> 使用自訂參數呼叫回呼。請注意,由於 QRL 是延遲載入的,因此呼叫需要 asyncawait

編輯教學