QWIK DOCS / V2

上下文

用 createContextId、useContextProvider 与 useContext 跨层共享状态。

约 2 分钟Qwik v210 / 19
本页目录3 节
  1. 三个 API 的职责
  2. 放什么进上下文
  3. 什么时候不用上下文

上下文用于跨越多层组件共享状态,避免把 props 一层层传下去。Qwik 的上下文由三部分组成:一个不可变的 id、一个 provider、一个 consumer。

tsxsrc/components/theme-context.ts
import { createContextId, type Signal } from '@qwik.dev/core';

export const ThemeContext = createContextId<Signal<'light' | 'dark'>>(
  'app.theme'
);
tsx提供与读取
import { component$, useContext, useContextProvider, useSignal } from '@qwik.dev/core';
import { ThemeContext } from './theme-context';

export const Root = component$(() => {
  const theme = useSignal<'light' | 'dark'>('light');
  useContextProvider(ThemeContext, theme);
  return <Child />;
});

export const Child = component$(() => {
  const theme = useContext(ThemeContext);
  return <button onClick$={() => (theme.value = 'dark')}>切换</button>;
});

01三个 API 的职责#

  • createContextId<T>(name):创建一个类型化的 id,本身不保存状态,可以在模块顶层复用。
  • useContextProvider(id, value):把值提供给当前组件及其后代,不会全局可见。
  • useContext(id):读取最近一层 provider 提供的值。

02放什么进上下文#

上下文适合放 signal、store、配置对象和服务实例。值同样需要遵守可序列化边界:服务端创建、客户端使用的对象应当可序列化;浏览器专属实例请用 noSerialize() 或在客户端重新创建。

tsxcode
const UserContext = createContextId<{ name: string }>('app.user');

useContextProvider(UserContext, { name: 'Ada' });

03什么时候不用上下文#

  • 只有一层父子关系时,props 更直观。
  • 只有单个页面使用的数据,放在路由组件内部即可。
  • 需要全局单例且跨路由共享时,可以放在根布局的 provider 中。