Передача замыканий
Параметры должны быть сериализуемыми, чтобы Qwik мог возобновлять и рендерить каждый компонент независимо от других компонентов на странице. Это создаёт проблему, если мы хотим передать обратный вызов дочернему компоненту. Обратные вызовы - это функции, а функции не являются непосредственно сериализуемыми, но они сериализуемы через $(), если их сначала преобразовать в QRL.
QRL-адреса
Передача функций через сериализуемые границы должна осуществляться через QRL-адреса. QRL - это сериализованная форма функции (смотри QRL в разделе "Дополнительно").
В Qwik есть удобные 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$}>пока</button>Создание новой функции обратного вызова для <button> и вызов QRL.
<button
onClick$={async () => {
await props.hello$?.invoke('мир');
}}
>
привет
</button>Эта форма позволяет элементу <button> вызывать функцию обратного вызова с пользовательскими параметрами. Обратите внимание, что для вызова требуются async и await, поскольку QRL являются лениво загружаемыми.