添加localStorage存储后首次加载报$rating.join不是函数错误如何解决
错误根因
你用的是带SSR的Svelte/SvelteKit框架,服务端渲染阶段browser变量为假值,此时rating store的初始化语句browser && (JSON.parse(sessionStorage.getItem("rating")) || [])返回值为false而非数组,因此模板中调用$rating.join()时会触发类型错误。切换页面走客户端路由时,代码运行在浏览器环境browser为真,store初始值正常为数组,错误自动消失。
最优解决方案(修改store初始化逻辑)
直接调整store的初始值回退规则,确保无论是否是浏览器环境,初始值始终为数组:
// Store 修改后代码 export const rating = writable( browser ? (JSON.parse(sessionStorage.getItem("rating")) || []) : [] ) rating.subscribe((val) => browser && sessionStorage.setItem("rating", JSON.stringify(val)))
这个方案不需要修改组件代码,修复后首次加载就不会报错,服务端渲染阶段拿到的是空数组,调用join和读取length属性都正常。
可选方案:用onMount控制渲染时机
如果不想改store代码,也可以在Filters组件中等待客户端挂载完成后再渲染依赖store的内容:
<!-- Filters Component 修改后代码 --> <script> import { onMount } from 'svelte'; import {rating} from "../stores/items"; const ratings = [1, 2, 3, 4, 5]; let mounted = false; onMount(() => { mounted = true; }) </script> {#if mounted} <div class="flex justify-center"> <!-- Ratings Filter --> <div class="multiselect"> <div class="selectBox rounded-sm shadow2 m-1 px-1" on:click={multiselect}> <select> <option >{#if $rating.length === 0} Rating: {:else} {$rating.join(", ")} {/if}</option > </select> <div class="overSelect dropdown" /> </div> <div class="checkboxes" id="ratingDropdown"> {#each ratings as ratingItem} <div class="flex"> <input type="checkbox" id={ratingItem} name="typeValues" bind:group={$rating} value={ratingItem} class="dropdown" /> <label for={ratingItem} class="dropdown">{ratingItem}</label> </div> {/each} </div> </div> {/if}
额外提示:你原来的代码里{#each ratings as ratings}变量名重复了,建议改成ratingItem避免潜在冲突。
内容的提问来源于stack exchange,提问作者user13302911
相关产品推荐
相关产品推荐

