Svelte商店很棒。它们使您可以在不同组件上共享数据,并使其保持反应性。一切都是自动完成的。这与其他所有框架都是完全独特的。没有尴尬的提供者是提供者的父母。事情只是适合苗条的魔法。有些人讨厌这个,我个人喜欢它。
话虽如此,不幸的是,Sveltekit并非如此。网络未来的当前预测将需要服务器组件。 Sveltekit,不是Svelte,尤其是现在它在1.0中,它将能够处理它。但是,大多数教程都是为Svelte编写的。我怀疑我们将在Sveltekit中使用商店看到很多书面代码。让我们解决问题以及如何解决问题。
1.请勿在端点,操作或加载功能中使用商店
商店将无法在服务器上正常工作,因此只是不要在服务器上使用它们。从技术上讲,您可以在检查browser
环境的情况下对负载功能进行例外,但是实际上,如果您具有正确的配置,则应在$page
变量中可用的所有内容。这也将阻止您意外宣布全局变量。只是不要做。总有更好的方法。
2.在孤立的组件中根本不使用商店
从技术上讲,您可以做到这一点,但是没有理由。有很多教程显示了此示例,但您不需要。如果您不是在组件上共享数据,请简单使用reactive declaration - $:。声明性的编程将使您不必管理订阅,而您不必担心通过任何道具。
3.请勿将商店作为参数传递
这似乎是有争议的,但是如果您考虑一下,这是有道理的。如果您仅在父母组件中使用商店,请参见#2。使变量被动或创建一个event dispatcher。
正确的方式
根据Svelte Docs的说法,处理此问题的官方方法是使用setContext
和getContext
。但是,我们要遵循最佳实践,特别是single responsibility principle。任何高级React工程师都会知道将钩子分为自己的组件。每个商店都应遵循相同的原则。
首先,创建一个可重复使用的useReadable
和useWritable
组件。这将为您处理上下文,因此您不必考虑它。
ssr-stores.ts
import { getContext, hasContext, setContext } from "svelte";
import { readable, writable } from "svelte/store";
// context for any type of store
export const useContextStore = <T, A>(
name: string,
fn: (value?: A) => T,
defaultValue?: A,
) => {
if (hasContext(name)) {
return getContext<T>(name);
}
const _value = fn(defaultValue);
setContext(name, _value);
return _value;
};
// writable store context
export const useWritable = <T>(name: string, value: T) => {
return useContextStore(name, writable, value);
};
// readable store context
export const useReadable = <T>(name: string, value: T) => {
return useContextStore(name, readable, value);
};
接下来,创建商店就像创建自定义写作一样。唯一的区别是您必须用字符串命名商店。在这里,我们使用dark
。
商店
export const useDarkMode = () => useWritable('dark', false);
最后,导入hook
将您的商店在组件中使用。然后,您可以像任何商店一样使用它。
<script lang="ts">
import { useDarkMode } from 'stores.ts';
...
const darkMode = useDarkMode();
</script>
{#if $darkMode}
// do something
{/if}
这样的美是,您根本不必考虑上下文;您只是导入钩子。
和定制商店...?
按照我的previous post进行定制商店。在这里,您可以像其他任何类型的商店一样使用它。
export const jokerStore = (value: string) = {
const { set, update, subscribe } = writable<string | null>(value);
return {
set,
update,
subscribe
setJoker: () => set('joker')
}
};
export const useJoker = () => {
return useContextStore('joker-store', 'harley', jokerStore);
};
最后的想法
我坚信应该将其内置到Sveltekit中,我们不必考虑一下。不幸的是,由于编码人员没有意识到可以共享一个全局变量,因此会有很多数据泄漏。 Svelte团队,请实现这一目标!有一个充满issues的手柄。也有过度复杂的工作和外部包(我有点喜欢地图版本),但是...曼达洛人会告诉您。
这就是方式...
查看code.build有关更多提示。我目前正在用尾风重建...
J