上下文
Qwik 提供了一個 context API,它解決了 props drilling 的問題,並且與 React 的函數式 useContext()
非常相似。事實上,Qwik 的 context API 是將數據傳遞給不同組件的最有效方式,它可以減少開銷、生成更少的代碼,並允許 Qwik 更有效地對未使用的數據進行 樹搖。
Qwik 的 context API 由 3 個方法組成,可以從 @builder.io/qwik
中導入
createContextId(contextName: string): ContextId
useContextProvider(ctx: ContextId, value: VALUE): void
useContext(ctx: ContextId): VALUE
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-context
的 ContextId
,並使用它為 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、數組或對象。
注意事項
- 提供的值不會在整個渲染樹中全局可用,而僅對樹中的後代組件可用。
- 如果在服務器端渲染 (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>
);
});