傳遞閉包
屬性必須是可序列化的,以便 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 是延遲載入的,因此呼叫需要 async
和 await
。