【问题标题】:weird behaviour with svelte store and routify $params,苗条商店和 routify $params 的奇怪行为,
【发布时间】:2020-09-21 03:14:15
【问题描述】:

我正在做一个论坛,所有消息都以某种方式相互链接。为了保存数据库读取,我将消息存储在 $messageStore 中作为 $messageStore[messageId]。 我正在使用 routify 的 $params 从 /message/id1 导航到 /message/id2 等,其中每个页面都包含 $params 中标识的消息,还有其他可能已经或可能不在商店中的链接消息。

我的问题是:

1st,组件没有卸载,所以当 $params 通过轻弹一个 1ms 的值来触发它时,它会禁用主组件的渲染并强制 init() 函数检查它需要在 DB 上获取的内容与否.. 这很丑陋,到目前为止它似乎工作,但我敢打赌这会失败,这取决于它运行的机器。

第二,在这样做之后,我遇到了一些我不明白的事情。 $messageStore 在页面更改时不会更改,但是突然之间我得到了很多未定义的值。似乎 $params 从 value1 变为 none 到 value2。 此外,如果我检查 init() 函数 if($messageStore[$params.id].someKey==="someValue"),它不会通过,尽管我确定它在商店中。

如果我这样做了

console.log($messageStore[$params.id].someKey)console.log($messageStore[$params.id].someKey==="someValue")if($messageStore[$params.id].someKey==="someValue"){console.log('passed')}else{console.log("failed")}

我明白了:

"someValue"
true
"failed"

这就像 console.log() 在执行时没有给出结果..

在使用 Routify 之前,我与 svelte-spa-router 拥有相同的东西,所以这可能是我在使用 svelte 和更改存储值和执行顺序时无法获得的东西..

我似乎找到了一种解决方法,方法是使用顶部组件中的作用域道具传递参数,该道具在页面更改时闪烁,但如果有人可以在那里教我一些东西,我将非常感激..

【问题讨论】:

    标签: javascript store lifecycle reactive svelte


    【解决方案1】:

    我对您想要实现的目标、您如何实现目标以及问题 1 感到困惑。首先,我将向您提出一些要点,这些要点可能有用,也可能没有帮助。我希望没关系。

    1. 应使用$: 处理反应性。 IE。收听您需要编写的商店的更改。 $: console.log($mystore)
    2. Routify 1.8 beta 支持服务工作者、离线可用性、外部资产的预取和缓存。这可能有助于处理对 API 的重复请求。
    3. 我正在使用 routify 的 $params 从 /message/id1 导航到 /message/id2 等

      ^这是什么意思?

    4. 能否在 Codesandbox 上复制该问题?

    我希望我能提供更多帮助,但这个问题感觉有点黑盒子。

    【讨论】:

    • 嗨,杰克。感谢您的回答。我对问题 1 的问题是 $messageStore 是一个大对象,当用户在页面上时我会对其应用更改,并且我不希望每次都重新计算所有内容。我很乐意使用 onMount,但组件似乎并没有在基于相同组件的两个不同页面之间卸载。问题是:如何替换 onMount(),当组件不卸载时,而不是基于它们使用的值。或者如何在参数更改时触发重新渲染?
    • 我会看看 routify1.8 beta,是的,我会尝试看看 codeandbox 是如何工作的..
    • 您应该能够使用$beforeUrlChange 和/或$afterPageLoad 来触发重新渲染。如果这是一个常见的用例,我们可以添加一个 $isChangingPage 助手。
    • 我认为我的问题来自于我不知道反应式语句。它现在运行良好^^
    【解决方案2】:

    我想我对图像做同样的事情,但我对你的用例有点困惑。对我来说,我有一个文件夹 gallery white 一个 index.svelte 和一个 [image].svelte。所以你可以去gallery/1gallery/2等等看不同的图片。而不是使用参数,只需使用export let image(或在您的情况下为export let id,来访问消息ID。然后您可以使用您的ID在$messagestore中获取正确的索引,例如:

    //this will get the the url param
    export let id
    //this will change every time your id chages, i.e. message/1 to message/2
    $: if (id) { 
        getIndex();
    }
    
     async function getIndex() {
    //make sure the message store has finished loading, you'd set this in the store
    await waitFor(() => $messageStoreLoaded === true);
    
    sIndex = await $messageStore.findIndex(p => p.id === id);
    //if for whatever reason the message is not in the store, do some error handling
    if (sIndex == -1) sIndex = -2;
    
    //keep a store of what index you're on, this is another writable store
    await messageStoreIndex.update(n => (n = sIndex));
    
    //load the new message data from the store
    newMessage = $storePics[$storePicsIndex];
    }
    
    function waitFor(conditionFunction) {
      const poll = (resolve) => {
        if (conditionFunction()) resolve("The Thing Finished");
    //you can get rid of the console.log, and change the millisenconds to whatever, I usually stick to 100 to 400 for most things
        else console.log("Still Wating..."), setTimeout((_) => poll(resolve), 200);
      };
      return new Promise(poll);
    }
    

    希望这能给你一个起点。您可以进行一次数据库调用来填充您的 messageStore,然后使用该函数跟踪您所在的索引。

    【讨论】:

    • 啊,谢谢!基本上我正在构建一个结构为树的论坛,其中主页是“/message/[id]/[sortKidsBy.value]/[sortKidsBy.order]” 我在每个页面上尝试做的是:1 - 反应到新地址 2-检查我们在商店中是否有主要消息 3-一旦我们得到它,检查我们是否已经有相同的请求 - 并获取孩子的 id 4-从商店或数据库中获取孩子的
    • 你的waitFor函数是什么?你店里有定制的吗?
    • this: $: if (id) { getIndex(); }。是我不知道我能做到的事情
    • 啊!是的,waitFor 是自定义的,只是来自另一个stackoverflow 问题的简单轮询:) 我将它添加到答案中。如果这能让你开始,请告诉我,如果你遇到问题,我会尽力提供帮助。
    • 是的,这是一个很好的答案,谢谢。它促使我购买了《行动中的苗条和工兵》这本书,试图通过在网络上到处收集碎片来巩固我认为我所理解的东西。有很多东西要从我自己开始几乎从零开始学习..
    猜你喜欢
    • 2023-02-21
    • 2021-05-11
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 2022-11-11
    • 2017-03-15
    • 1970-01-01
    相关资源
    最近更新 更多