在 Sapper 的导航中单击重新导航按钮时更新路线

Updating a route when re-navigation button is clicked in nav in Sapper

我有一个包含搜索栏的导航栏,如果该路线当前不是搜索栏的路线,它就可以正常工作。但是,我希望能够在路线内进行搜索,但组件不会重新 运行。

我目前正在 运行 onMount,但已经尝试过 beforeUpdate 和 afterUpdate。我也试过将它作为函数放在脚本中,但它没有更新。

数据首先从搜索栏传递到商店,然后新路由从商店获取数据。这可能不太理想,但我没有找到传递它的方法,因为它位于导航栏中。

这是搜索栏的代码,我尝试使用 replaceState: True,但似乎没有任何效果。

async function sendSearchTerms(terms) {
    await goto("recipe", { replaceState: true });
    searchItems.set(terms);
}

这是重定向到的路由中的代码。

let unsubscribe;
let allIngredients;
let allRecipes;
let error;

onMount(async () => {
    unsubscribe = searchItems.subscribe((items) => {
        allIngredients = items;
    });

    const ingredients = fixTextArray(allIngredients);
    console.log(ingredients);
    if (ingredients) {
        try {
            const res = await fetch("dev_data/recipes.json");
            if (res.status == 200) {
                allRecipes = await res.json();
            } else {
                error = res.status;
            }
        } catch (err) {
            alert(err);
        }
    } else {
        console.log("CRAP");
    }
});

onDestroy(() => {
    if (unsubscribe) {
        unsubscribe();
    }
});

如果我从另一条路线搜索,结果很好,所以我最初的想法是替换 onMount,因为它已经挂载了。但这什么也没做,所以我猜 Sapper 有点在某个地方保持状态,不会强制重新加载相同的路由。

也许标记中可能有一些东西可以做到这一点,所以我也包括了它:

{#if error}
    <h1>{error}</h1>
{:else}
    {#if allRecipes}
        <div class="cards">
            {#each allRecipes as recipe}
                <Card title={recipe.title} link="/{recipe.id}" />
            {:else}Loading{/each}
        </div>
    {:else}No recipes{/if}
{/if}

您可以将获取食谱的代码移出 onMount 并将其设置为单独的反应块:

let unsubscribe;
let allIngredients;
let allRecipes;
let error;

$: allIngredients && getRecipes(allIngredients)

const getRecipes = (allIngredients) => {
    const ingredients = fixTextArray(allIngredients);
    console.log(ingredients);
    if (ingredients) {
        try {
            const res = await fetch("dev_data/recipes.json");
            if (res.status == 200) {
                allRecipes = await res.json();
            } else {
                error = res.status;
            }
        } catch (err) {
            alert(err);
        }
    } else {
        console.log("CRAP");
    }
}

onMount(async () => {
    unsubscribe = searchItems.subscribe((items) => {
        allIngredients = items;
    });
})

onDestroy(() => {
    if (unsubscribe) {
        unsubscribe();
    }
});

$: allIngredients && getRecipes(allIngredients)将在allIngredients改变时执行,如果它是假的它会停止,否则它会运行 getRecipes 并得到食谱,更新其他变量。