Контекст

Qwik предоставляет API контекста, который решает проблему проброса параметров и очень похож на useContext() от фреймворка React. На самом деле, API контекста Qwik является наиболее эффективным способом передачи данных различным компонентам, что снижает накладные расходы, генерирует меньше кода и позволяет Qwik более интенсивно тришейкать неиспользуемые данные.

API контекста Qwik состоит из 3 методов, импортируемых из @builder.io/qwik:

import { type Signal, component$, useSignal } from '@builder.io/qwik';
import {
  useContext,
  useContextProvider,
  createContextId,
} from '@builder.io/qwik';
 
export const ThemeContext = createContextId<Signal<string>>(
  'docs.theme-context'
);
 
export default component$(() => {
  const theme = useSignal('dark');
  useContextProvider(ThemeContext, theme);
  return (
    <>
      <button
        onClick$={() =>
          (theme.value = theme.value == 'dark' ? 'light' : 'dark')
        }
      >
        Flip
      </button>
      <Child />
    </>
  );
});
 
const Child = component$(() => {
  const theme = useContext(ThemeContext);
  return <div>Тема: {theme.value}</div>;
});

В приведённом выше примере мы создаем ContextId с именем docs.theme-context и затем используем его для предоставления useSignal компоненту default. Компонент Child затем использует метод useContext для получения useSignal и рендера его значения.

createContextId()

Этот метод используется для создания нового ContextId.

export interface GenericType {
  ...
}
 
export const QwikCityContext = createContextId<GenericType>(name: string): ContextId<GenericType>;

Параметры

  • name: это уникальная строка, передаваемая в createContextId как идентификатор контекста. Это позволяет избежать конфликтов при наличии нескольких контекстов. Рекомендуется использовать соглашение об именовании, например, io.builder.qwik.city.

Возвращает

Обратите внимание, что значение, возвращаемое createContextId(), не содержит никакого состояния, это неизменяемый ID объекта наподобие { id: 'io.builder.qwik.city' }. Оно используется только для описания имени и типа контекста, как адрес или идентификатор.

Поскольку оно не хранит никакого состояния, его можно вызвать и сделать синглтоном, и экспортирует его в какой-нибудь общий модуль.

useContextProvider()

Этот метод используется для создания контекста для определённого компонента и его потомков, используя ContextId в качестве ключевого идентификатора контекста.

src/components/Parent.tsx
import { component$, useStore, useContextProvider } from '@builder.io/qwik';
 
export const Parent = component$(() => {
 
  const qwikCityObject = useStore<GenericType>({
    ...
  });
 
  useContextProvider(QwikCityContext, qwikCityObject);
  useContextProvider(PlainArrayContext, [1, 2, 3])
  useContextProvider(AppNameContext, "My Qwik App")
 
  return (
      <Children />
  );
});

Параметры

  • ContextId: представляет имя созданного ранее контекста, которое будет служить идентификатором для предоставляемых данных (второй параметр).

  • data: вы можете предоставить любой тип данных, например useSignal, useStore из Qwik, Array, Objects.

Предостережения

  • Предоставленное значение будет доступно не глобально для всего дерева рендера, а только для компонентов-потомков в дереве.
  • Если контекст не используется во время SSR, то он не будет сериализован. Поэтому если вы хотите, чтобы контекст был доступен на клиенте, даже если вы не используете его во время SSR, вы можете вызвать useContext() в родительском компоненте, чтобы заставить его сериализоваться.

useContext()

Этот метод используется для получения значения из Context-а, который предоставляется родительским компонентом.

src/components/Children.tsx
import { component$, useContext } from '@builder.io/qwik';
 
export const Children = component$(() => {
  const qwikCityObject = useContext(QwikCityContext);
  const plainArray = useContext(PlainArrayContext);
  const appName = useContext(AppNameContext);
 
  return (
      <div>Дочерние компоненты могут использовать любое из предоставленных контекстом значений, например {appName}</div>
  );
});

Участники

Спасибо всем участникам, которые помогли сделать эту документацию лучше!

  • manucorporat
  • RATIU5
  • nnelgxorz
  • adamdbradley
  • the-r3aper7
  • cunzaizhuyi
  • forresst
  • kerbelp
  • shairez
  • mhevery
  • AnthonyPAlicea
  • steve8708
  • mrhoodz