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

Svelte中localStorage更新时如何同步Store?MERN登录异常求助

问题描述

我是MERN栈初学者,正在开发支持用户注册、登录、登出的简易博客项目。当前遇到的问题:首次登录时user store显示为null,但刷新页面后能正常显示当前用户数据,尝试多种方法未解决。


相关代码

Store.js

import { writable } from "svelte/store";

const URL = writable("http://localhost:8080/auth/registeration");
let user = writable(JSON.parse(localStorage.getItem("user")));

export { URL, user };

Login.svelte

<script>
    import axios from "axios";
    import { user } from "../store";
    import { URL } from "../store.js";
    import { link, push } from "svelte-spa-router";

    let email;
    let password;
    let error;
    const login = async () => {
        const obj = {
            email: email,
            password: password,
        };
        try {
            const result = await axios.post(`${$URL}/Login`, obj);
            const token = result.data.token;
            if (result.data.massage === "Successfully login") {
                push("/Deshboard");
                document.cookie = `token=${token}`;
                const userData = result.data.others;
                saveTolocal(userData);
            } else {
                error = result.data.massage;
            }
        } catch (error) {
            error = error.massage;
        }
    };

    const saveTolocal = (userData) => {
        const store = localStorage.setItem("user", JSON.stringify(userData));
        console.log($user);
    };
</script>

<div class="container">
    <div class="wrapper">
        <h2>Login.</h2>
        <form on:submit|preventDefault={login}>
            <div class="UserAndLastName inline">
                <div class="email">
                    <label for="Email">Email:</label>
                    <input
                        type="text"
                        placeholder="Email"
                        id="Email"
                        autocomplete="off"
                        required
                        bind:value={email}
                    />
                </div>
            </div>
            <div class="PasswordAndHobbies inline">
                <div class="password">
                    <label for="password">Password:</label>
                    <input
                        type="password"
                        name="password"
                        id="password"
                        required
                        placeholder="Password"
                        bind:value={password}
                    />
                </div>
            </div>
            <button type="submit">Login</button>
        </form>
        {#if error}
            <h3 class="red">{error}</h3>
        {/if}
        <a href="/" use:link>Did't have an account?</a>
    </div>
</div>

Logout.svelte

const logout = async () => {
    const token = document.cookie;
    const real_token = token.slice(token.indexOf("=") + 1);
    axios.defaults.headers.common["Authorization"] = real_token;
    const result = await axios.post(`${$URL}/Logout`);
    if (result.data.massage == "Logout successful") {
        document.cookie = "token=null";
        localStorage.setItem("user", JSON.stringify(null));
        push("/Login");
    }
};

解决方案

问题核心:你仅将用户数据存入localStorage,但未同步更新Svelte的user store。Svelte store不会自动监听localStorage变化,因此首次登录时store仍为初始化时的null,刷新页面后store重新读取localStorage数据才会正常显示。

修复步骤

  1. 更新Login.svelte中的saveTolocal函数
    在保存数据到localStorage后,直接调用store的set方法更新值:

    const saveTolocal = (userData) => {
        localStorage.setItem("user", JSON.stringify(userData));
        user.set(userData); // 新增:更新store
        console.log($user); // 现在会输出正确的用户数据
    };
    
  2. 优化Store.js的store逻辑(可选)
    给user store添加订阅,实现store与localStorage双向同步,避免其他场景下数据不一致:

    import { writable } from "svelte/store";
    
    const URL = writable("http://localhost:8080/auth/registeration");
    
    const createUserStore = () => {
        const { subscribe, set } = writable(JSON.parse(localStorage.getItem("user")));
    
        // 订阅store变化,自动同步到localStorage
        subscribe(value => {
            localStorage.setItem("user", JSON.stringify(value));
        });
    
        return {
            subscribe,
            set,
            logout: () => set(null) // 统一登出方法
        };
    };
    
    const user = createUserStore();
    
    export { URL, user };
    
  3. 修改Logout.svelte的登出逻辑
    如果使用了优化后的store,直接调用store的logout方法即可自动同步localStorage:

    const logout = async () => {
        const token = document.cookie;
        const real_token = token.slice(token.indexOf("=") + 1);
        axios.defaults.headers.common["Authorization"] = real_token;
        const result = await axios.post(`${$URL}/Logout`);
        if (result.data.massage == "Logout successful") {
            document.cookie = "token=null";
            user.logout(); // 调用store方法同步数据
            push("/Login");
        }
    };
    

修改后,首次登录时user store会立即更新,无需刷新页面即可获取当前用户数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:05:54