【问题标题】:Error in Svelte when removing data from a writable store that is reference by reactive variable从反应变量引用的可写存储中删除数据时,Svelte 出错
【发布时间】:2021-05-27 04:35:06
【问题描述】:

我在尝试从商店中删除商品时遇到了问题。我有一个路由 /view/:id 并使用该 id 从自定义可写存储 (items) 访问一个值。我编写了一个简单的选择器方法来根据 id 检索项目数据,并创建了一个响应式 $: item 变量来监听更改(可以在此视图中编辑项目)。以下是我<script>的详细信息

// ItemView.svelte
export let params: { id?: string } = {};
import { push } from "svelte-spa-router";
import { items } from "./stores/items";

$: [item] = items.select($items, params.id);

function handleDelete() {
  if (confirm("Are you sure you want to delete this item?")) {
    items.delete(item.id);
    push("/");
  }
}

当我调用handleDelete 时,我收到以下错误:

Uncaught (in promise) TypeError: can't access property "type", ctx[0] is undefined
    update bundle.js:3796
    update index.mjs:764
    flush index.mjs:732
    promise callback*schedule_update index.mjs:707
    make_dirty index.mjs:1442
    ctx index.mjs:1477
    7 bundle.js:3898
    set index.mjs:35
    update index.mjs:43
    delete items.ts:59
    handleDelete ItemView.svelte:17

如果我将items.delete(item.id) 包裹在超时中,那么一切正常(5 毫秒就可以了),但这似乎不对。我对 Svelte 没有太多经验,但感觉问题在于反应变量取消订阅。我应该以不同的方式获取单项数据吗?导航前是否需要手动取消订阅?

我尝试手动拨打unsubscribe,但也没有用:

export let params: { id?: string } = {};
import { push } from "svelte-spa-router";
import { items } from "./stores/items";
import { onDestroy } from "svelte";

let item;

const unsubscribe = items.subscribe(
  (value) => (item = items.select(value, params.id)[0])
);

function handleDelete() {
  if (confirm("Are you sure you want to delete this item?")) {
    unsubscribe(); // <- Here
    items.delete(item.id);
    push("/");
  }
}

onDestroy(unsubscribe);

这给了我以下错误:

Uncaught (in promise) TypeError: stop is not a function
    subscribe index.mjs:58
    run index.mjs:18
    run_all index.mjs:24
    destroy_component index.mjs:1431
    update bundle.js:918

我不承诺我发布的任何代码;我只是希望能够查看单个项目,然后将其删除并离开。

【问题讨论】:

  • 您也可以发布您的商店代码吗?
  • 也许你让它变得比必要的更复杂。试试这个来获取项目$: item = $items.find(o =&gt; o.id == params.id); 并删除它$items = $items.splice($items.findIndex(o =&gt; o.id == params.id), 1);
  • @Molda 看起来可以。我的 select 函数提供了一些我不想丢失的附加排序实用程序。

标签: javascript svelte svelte-3


【解决方案1】:

我了解到错误消息中的ctx 指的是反应式变量赋值的右侧。在本例中,这是我的 select 方法的返回值:items.select($items, params.id)

ctx[0] 是该数组中的第一项,或者是我通过解构创建的变量:$: [item]

所以当 Svelte 说ctx[0] is undefined 时,意味着ctx 数组中没有第一个条目; item 未定义(因为它已被删除)。

我认为属性“类型”有些重要,但它最终只是我试图在标记中访问的item 上的第一个键:{item.type}。尝试访问任何属性都会失败。

通过将所有内容包装在 {#if item} 条件中,我能够解决错误:

<!-- ItemView.svelte -->
{# if item}
<p>Type: {item.type}</p>
{/if}

我不会推荐以上任何一种作为遵循的好模式。但如果您正在寻求解决类似问题,请考虑此解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-09
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 2014-03-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多