上下文

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 组件提供一个 useSignal。然后,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:可以提供任何数据类型,如 Qwik 的 useSignal、useStore、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>Child components can use any of the provided values, such as {appName}</div>
  );
});

Contributors

Thanks to all the contributors who have helped make this documentation better!

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