在Sveltekit中使用商店的正确方法
#javascript #网络开发人员 #svelte #sveltekit

Svelte商店很棒。它们使您可以在不同组件上共享数据,并使其保持反应性。一切都是自动完成的。这与其他所有框架都是完全独特的。没有尴尬的提供者是提供者的父母。事情只是适合苗条的魔法。有些人讨厌这个,我个人喜欢它。

话虽如此,不幸的是,Sveltekit并非如此。网络未来的当前预测将需要服务器组件。 Sveltekit,不是Svelte,尤其是现在它在1.0中,它将能够处理它。但是,大多数教程都是为Svelte编写的。我怀疑我们将在Sveltekit中使用商店看到很多书面代码。让我们解决问题以及如何解决问题。

1.请勿在端点,操作或加载功能中使用商店

商店将无法在服务器上正常工作,因此只是不要在服务器上使用它们。从技术上讲,您可以在检查browser环境的情况下对负载功能进行例外,但是实际上,如果您具有正确的配置,则应在$page变量中可用的所有内容。这也将阻止您意外宣布全局变量。只是不要做。总有更好的方法。

2.在孤立的组件中根本不使用商店

从技术上讲,您可以做到这一点,但是没有理由。有很多教程显示了此示例,但您不需要。如果您不是在组件上共享数据,请简单使用reactive declaration - $:。声明性的编程将使您不必管理订阅,而您不必担心通过任何道具。

3.请勿将商店作为参数传递

这似乎是有争议的,但是如果您考虑一下,这是有道理的。如果您仅在父母组件中使用商店,请参见#2。使变量被动或创建一个event dispatcher

正确的方式

根据Svelte Docs的说法,处理此问题的官方方法是使用setContextgetContext。但是,我们要遵循最佳实践,特别是single responsibility principle。任何高级React工程师都会知道将钩子分为自己的组件。每个商店都应遵循相同的原则。

首先,创建一个可重复使用的useReadableuseWritable组件。这将为您处理上下文,因此您不必考虑它。

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