You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sveltekit:使用Store与localStorage刷新时数据显示异常问题

问题描述

我用localStorage做数据持久化,功能本身正常,但刷新页面时会先显示初始值0,之后才加载localStorage里的真实值。有没有办法直接获取localStorage的值,避免先显示0?还是说这个情况没法解决?

我的Store代码

import { writable } from 'svelte/store';
import { clickPower } from "$lib/store";
import { browser } from "$app/environment";

/** 这是烤肉串数量达到过的最高值 **/
export function createHighest() {
    const { subscribe, set } = writable(0);

    return {
        subscribe,
        set: (value: number) => set(value),
        reset: () => set(0),
    };
}

/** 总烤肉串数量 **/
export function createTotal() {
    const localTotal = browser && localStorage.getItem("totalKebabs");
    const totalStore = writable(localTotal ? parseInt(localTotal) : 0);
    const { subscribe, set, update } = totalStore;

    return {
        subscribe,
        // 我的其他函数写在这里
        ....
    };
}

显示代码

{#key $totalKebabs}
    <span>{$totalKebabs}</span>
    烤肉串
{/key}

解决方法

问题根源是Svelte/Kit的服务端渲染(SSR)逻辑:服务端执行createTotal时,browser为false,无法读取localStorage,所以store初始值设为0。等到客户端 hydration 完成后,才会加载localStorage的值,导致页面先显示0再跳转的闪烁。

方案1:修改Store,客户端初始化时直接加载本地数据

调整createTotal函数,让它在客户端环境下优先读取localStorage并更新store,避免初始值闪烁:

export function createTotal() {
    // 先设初始值为0,后续在客户端覆盖
    const totalStore = writable(0);
    const { subscribe, set, update } = totalStore;

    // 仅在客户端执行,读取本地存储并更新
    if (browser) {
        const savedTotal = localStorage.getItem("totalKebabs");
        if (savedTotal) {
            set(parseInt(savedTotal));
        }
    }

    // 扩展set和update方法,确保修改时同步到localStorage
    return {
        subscribe,
        set: (value: number) => {
            set(value);
            if (browser) {
                localStorage.setItem("totalKebabs", value.toString());
            }
        },
        update: (updater) => {
            update(prev => {
                const newValue = updater(prev);
                if (browser) {
                    localStorage.setItem("totalKebabs", newValue.toString());
                }
                return newValue;
            });
        },
        // 你的其他函数...
    };
}

方案2:在组件中用onMount初始化数据

如果不想改动store,可以在使用store的组件里,通过onMount(仅客户端执行)读取localStorage并更新store:

<script>
    import { onMount } from 'svelte';
    import { totalKebabs } from '$lib/store';

    onMount(() => {
        const savedTotal = localStorage.getItem("totalKebabs");
        if (savedTotal) {
            totalKebabs.set(parseInt(savedTotal));
        }
    });
</script>

<span>{$totalKebabs}</span>
烤肉串

额外优化:减少视觉闪烁

可以给显示区域加个加载判断,直到数据加载完成再显示:

<script>
    import { onMount } from 'svelte';
    import { totalKebabs } from '$lib/store';
    let dataLoaded = false;

    onMount(() => {
        const savedTotal = localStorage.getItem("totalKebabs");
        if (savedTotal) {
            totalKebabs.set(parseInt(savedTotal));
        }
        dataLoaded = true;
    });
</script>

{#if dataLoaded}
    <span>{$totalKebabs}</span>
    烤肉串
{/if}

内容的提问来源于stack exchange,提问作者user3818418

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 11:53:17