上下文

Qwik 提供了一个上下文 API,它解决了道具传递的问题,并且与 React 的函数式 useContext() 非常相似。事实上,Qwik 的上下文 API 是传递数据到不同组件的最有效方式,它减少了开销,生成了更少的代码,并允许 Qwik 更有效地 摇树 未使用的數據。

Qwik 的上下文 API 由 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 is {theme.value}</div>;
});

在上面的示例中,创建了一个名为 docs.theme-contextContextId,并用于向 default 组件提供 useSignalChild 组件使用 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: 你可以提供任何数据类型,例如 Qwik 的 useSignal、useStore、数组或对象。

注意事项

  • 提供的 value 不会在整个渲染树中全局可用,而只会对树中的后代组件可用。
  • 如果在服务器端渲染 (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>Child components can use any of the provided values, such as {appName}</div>
  );
});

贡献者

感谢所有帮助改进此文档的贡献者!

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