Svelte 5:如何跨组件/模块反应性地传递原语

问题描述 投票:0回答:1

我有几十个反应式原始值(例如

div_status = "frozen"
),我需要在组件/模块边界之间传递,包括
+page.svelte
文件和
svelte.js
模块
。这些值表示 UI 的可更改属性,因此将影响 (a) 样式以及 (b) 某些事件侦听器内用于用户交互的 if-else 块。重要的是,这些值需要在拖动级别上“反应式”,因为 UI 必须在用户拖动时做出响应(例如,将鼠标悬停在拖放区域上、拖动特定距离等) 将我的代码库转换为 Svelte 5,我不确定对于此用例是否使用商店或

$state()


    我的商店问题是,我无法在
  • svelte.js

    模块的导出函数中使用它们。此外,它们

    很难重构

  • 我对原语使用
  • $state()

    (如

    $state("frozen")
    )的问题是,我必须使事情复杂化,以免
    重新分配/覆盖
    状态:因此,为了改变它们的值,我要么将多个基元组合到对象数组中或将它们单独炸毁(例如 div_status = {value: "frozen"})。
    
    

  • 最后,我很困惑,我是否应该研究 getter/setter 如何工作,以及 store 或
$state()

的选择是否取决于我选择使用 context-API 还是只是将它们作为 props 传递。总而言之,我正在寻找一个易于重构的解决方案。

更新

与此同时,我设法更新
svelte.js

文件内的商店,如下所示:

stores.js

export let simpleStore = writable(1); export let comboStore = writable({a:1});

helpers.svelte.js

import { simpleStore, comboStore } from '$lib/stores.js' export function handleIncrease() { simpleStore.update(value => value + 1); comboStore.update(value => { return { ...value, a: value.a + 1 }; }); }

+page.svelte

<script> import { simpleStore, comboStore } from '$lib/stores.js' </script> <p>{$simpleStore}</p> <p>{$comboStore.a}</p> <button onclick={handleIncrease}>Increase a</button>


components svelte reactive-programming svelte-5
1个回答
0
投票
$state

本身并不是问题。按值传递的原语会阻止更新;这也可以在普通 JS 中观察到,例如

function createCounter() { let value = 0; setTimeout(() => value++); // happens later return value; } const counter = createCounter(); console.log('Value copied', counter) setTimeout(() => console.log('Value copied', counter), 1);

您需要通过函数或访问器属性维护对该值的

引用

function createCounter() { let value = 0; setTimeout(() => value++); // happens later return () => value; } const counter = createCounter(); console.log('Value referenced', counter()) setTimeout(() => console.log('Value referenced', counter()), 1);

一般来说,在 Svelte 5 中应该在商店上使用符文;商店可能会在以后的版本中被弃用,因为符文应该能够取代它们。

如果您处于只读状态,您可以返回一个如上例所示的函数,并通过

$derived.by

“接收”该函数。例如

function createCounter() {
    let value = $state(0);
    setTimeout(() => value++); // happens later
    
    return () => value;
}

const counter = $derived.by(createCounter());
$inspect('Counter', counter);

预览 REPL

1 对于写访问,还有各种选项,例如使用两个函数(获取/设置)或使用

{ value }

框。盒子方法可能是最灵活的,因为它允许将对象用于诸如

bind:value={...}
之类的事情。
您还可以轻松地将这样的对象传递到上下文中;上下文主要用于将某些内容传递到组件层次结构的多个级别。如前所述,通过 props,您可以直接使用值的绑定来发送和接收值的更新。

拥有许多正在传递的原语可能暗示着优化机会。也许其中一些可以分组并放在一个更大的

$state

对象上,其属性名称比“值”更有意义。

使用什么通常取决于当前的具体问题。有时,仅提供对状态和定制更新功能的读取访问可能是最好的方法。


1 链接稍后可能会中断并需要更新。

© www.soinside.com 2019 - 2024. All rights reserved.