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数据才会正常显示。
修复步骤
更新Login.svelte中的
saveTolocal函数
在保存数据到localStorage后,直接调用store的set方法更新值:const saveTolocal = (userData) => { localStorage.setItem("user", JSON.stringify(userData)); user.set(userData); // 新增:更新store console.log($user); // 现在会输出正确的用户数据 };优化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 };修改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
相关产品推荐
相关产品推荐

