上下文允许组件访问父组件拥有的值,而无需将它们作为 props 传递下来(可能通过许多中间组件层,称为'prop-drilling')。父组件使用`setContext(key, value)`设置上下文...
```svelte
```
...并且孩子使用`getContext`检索它:
```svelte
{message}, inside Child.svelte
```
这在`Parent.svelte`不直接了解`Child.svelte`时尤其有用,而是将其作为`children`[片段](snippet)([演示](/playground/untitled#H4sIAAAAAAAAE42Q3W6DMAyFX8WyJgESK-oto6hTX2D3YxcM3IIUQpR40yqUd58CrCXsp7tL7HNsf2dAWXaEKR56yfTBGOOxFWQwfR6Qz8q1XAHjL-GjUhvzToJd7bU09FO9ctMkG0wxM5VuFeeFLLjtVK8ZnkpNkuGo-w6CTTJ9Z3PwsBAemlbUF934W8iy5DpaZtOUcU02-ZLcaS51jHEkTFm_kY1_wfOO8QnXrb8hBzDEc6pgZ4gFoyz4KgiD7nxfTe8ghqAhIfrJ46cTzVZBbkPlODVJsLCDO6V7ZcJoncyw1yRr0hd1GNn_ZbEM3I9i1bmVxOlWElUvDUNHxpQngt3C4CXzjS1rtvkw22wMrTRtTbC8Lkuabe7jvthPPe3DofYCAAA=))的一部分进行渲染:
```svelte
```
关键(如示例中所示 `'my-context'`)和上下文本身可以是任何 JavaScript 值。
除了 [`setContext`](svelte#setContext) 和 [`getContext`](svelte#getContext),Svelte 还暴露了 [`hasContext`](svelte#hasContext) 和 [`getAllContexts`](svelte#getAllContexts) 函数。
##
使用上下文与状态
您可以将响应式状态存储在上下文中([demo](/playground/untitled#H4sIAAAAAAAAE41R0W6DMAz8FSuaBNUQdK8MkKZ-wh7HHihzu6hgosRMm1D-fUpSVNq12x4iEvvOx_kmQU2PIhfP3DCCJGgHYvxkkYid7NCI_GUS_KUcxhVEMjOelErNB3bsatvG4LW6n0ZsRC4K02qpuKqpZtmrQTNMYJA3QRAs7PTQQxS40eMCt3mX3duxnWb-lS5h7nTI0A4jMWoo4c44P_Hku-zrOazdy64chWo-ScfRkRgl8wgHKrLTH1OxHZkHgoHaTraHcopXUFYzPPVfuC_hwQaD1GrskdiNCdQwJljJqlvXfyqVsA5CGg0uRUQifHw56xFtciO75QrP07vo_JXf_tf8yK2ezDKY_ZWt_1y2qqYzv7bI1IW1V_sN19m-07wCAAA=))...
```svelte
```
...尽管请注意,如果您不是更新而是重新分配 *计数器*`counter`,您将“断开链接”——换句话说,不是这个...
```svelte
```
...你必须这样做:
```svelte
```
Svelte 会警告你如果做错了。
##
类型安全的上下文
一种有用的模式是将对 `setContext` 和 `getContext` 的调用封装在辅助函数中,这样您可以保留类型安全:
```js
/// file: context.js
// @filename: ambient.d.ts
interface User {}
// @filename: index.js
// ---cut---
import { getContext, setContext } from 'svelte';
const key = {};
/** @param {User} user */
export function setUserContext(user) {
setContext(key, user);
}
export function getUserContext() {
return /** @type {User} */ (getContext(key));
}
```
##
替换全局状态
当你有多个不同组件共享的状态时,你可能想将其放入自己的模块中,并在需要的地方导入它:
```js
/// file: state.svelte.js
export const myGlobalState = $state({
user: {
// ...
}
// ...
});
```
在许多情况下这完全没问题,但存在风险:如果在服务器端渲染期间修改状态(虽然不推荐,但完全可能!)...
```svelte
```
...然后数据可能被下一个用户通过*next*访问。上下文解决了这个问题,因为它不会在请求之间共享。