---
# System prepended metadata

title: Passing Closures
tags: [Component Props]

---

# Passing Closures

> * 如有錯誤處指正或任何建議，懇請留言，感謝!
> * 搭配 ChatGPT 進行翻譯，請小心服用
> * ▸ ... 為英文原文


:::spoiler ...
Props must be serializable so that Qwik can resume and render each component independently from other components on the page. This poses a problem if we wish to pass a callback to a child component. Callbacks are functions and functions are not directly serializable, but they are serializable through the `$()` by converting them to QRLs first.
:::

`Pros` 必須是可序列化的，才能讓 Qwik 在頁面上獨立於其他元件之外恢復並渲染每個元件。如果我們希望將回呼函式傳遞給子元件，則會出現問題。回呼函式是函式，函式不能直接序列化，但是可以通過 `$()` 將它們轉換為 `QRLs` 後進行序列化。

## QRLs

:::spoiler ...
Functions passing across serializable boundaries must be done through QRLs. QRLs are serialized forms of a function. (See [QRL](https://qwik.builder.io/docs/advanced/qrl/) in advanced section.)
:::

必須通過 QRLs 在可序列化的界線之間傳遞函式。 QRLs 是函式的序列化形式。（請在進階部分查看 [QRL](https://qwik.builder.io/docs/advanced/qrl/) 。)


:::spoiler ...
Qwik has convenience APIs which end in `$` that are equivalent to calling `$()` directly. These two lines are equivalent:

-   inline: `useTask$(() => {...}/>`
-   explicit: `const callbackQrl = $(() => {...}); useTaskQrl(callbackQrl)`
:::

Qwik 有以 `$` 結尾的便利 API ，使用它就等同於直接使用 `$()`。以下兩行有一樣的效果：

- 以 `$` 結尾： `useTask$(() => {...}/>`
- 直接使用 `$()` ： `const callbackQrl = $(() => {...}); useTaskQrl(callbackQrl)`

:::spoiler ...
Most of the time we use the first form as it allows us to inline our callbacks directly into the API. But at times it is necessary to use the second form so that we can separate where the function is declared and where it is used.
:::

大多數情況下，我們使用第一種形式，因為它允許我們直接將回呼函式內嵌到 API 中。但有時必須使用第二種形式，以便我們可以分開定義函式和使用函式的位置。

:::spoiler ...
## Declaring callback props
:::

## 定義回呼函式的 Props

:::spoiler ...
A component can declare a callback in its props by:

-   Property that ends in `$` (as in `goodbye$`)
-   The type of the property is `PropFunction<T>` where `T` is the lazy reference type that the QRL points to (function signature).
:::

元件可以透過以下方式在其 `props` 中聲明回呼函式的存在：

```jsx
interface MyComponentProps {
  goodbye$: PropFunction<() => void>;
  hello$: PropFunction<() => void>;
}

export const MyComponent = component$((props: MyComponentProps) => { ... });
```

:::spoiler ...
This allows the user of `<MyComponent>` to use `goodbye$` form as shown here:
:::

如此一來，使用 `<MyComponent>` 時就可以使用 `goodbye$` 來傳遞回呼函式，如下所示：

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

:::spoiler ...
## Using callback props
:::

## 使用回呼函式的 Props

:::spoiler ...
Notice that the `<MyComponent>` component receives a callback function.
:::

注意， `<MyComponent>` 元件接受一個回呼函式。

:::spoiler ...
Passing the `props.goodbye$` as a reference to the `<button>`
:::

將 `props.goodbye$` 作為對 `<button>` 的引用傳遞

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

:::spoiler ...
Creating a new callback for `<button>` and internally invoking the callback QRL.
:::

為 `<button>` 創造一個新的回呼函式，並在內部使用回呼 QRL。

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

:::spoiler ...
This form allows the `<button>` to invoke the callback with custom parameters. Notice that the invocation requires `async` and `await` as the QRLs are lazy-loaded.
::: 

這種形式允許 `<button>` 使用自定義參數呼叫回呼函式。請注意，必須搭配 `async` 與 `await` 使用，因為 QRLs 是延遲載入的。

[下一步： 隱式模板更新](https://hackmd.io/II01YoaqTUezUdUOzNTOIg)

###### tags: `Component Props`