如何在不关闭SSR的情况下基于Store响应式变量触发Fetch请求?
无需关闭SSR的解决方案
问题根源
你之前的代码刷新崩溃主要有两个原因:
- SSR阶段Store无初始值:服务器端渲染时,
dateStore/shiftStore可能未初始化,导致date或shift为undefined,调用toISOString()直接抛出错误。 - 服务器端fetch相对URL失效:原生
fetch在服务器端无法解析相对URL(缺少浏览器环境的origin),导致请求失败。
正确实现步骤
1. 给Store设置初始有效值
确保Store在SSR和客户端都有可用的初始值,避免undefined报错:
// lib/store.js import { writable } from 'svelte/store'; // 初始日期设为当前日期 const initialDate = new Date(); export const dateStore = writable(initialDate); // 初始shift设为有效默认值(比如'1') export const shiftStore = writable('1');
2. 修改+page.js的load函数(处理SSR初始数据)
使用SvelteKit提供的fetch参数(自动处理SSR的URL解析和代理),同时通过get方法获取Store初始值:
import { dateStore, shiftStore } from '../../../lib/store'; import { get } from 'svelte/store'; export const load = async ({ fetch }) => { const date = get(dateStore); const shift = get(shiftStore); const dateStr = date.toISOString().split('T')[0]; // 获取初始评论数据 const getComments = async () => { const res = await fetch(`/api/${dateStr}/${shift}/1`); return res.json(); }; // 获取初始区域数据 const getAreas = async () => { const res = await fetch(`/api/api/TurnReportArea/1/${dateStr}/${shift}`); return res.json(); }; return { comments: getComments(), areas: getAreas() }; };
3. 修改+page.svelte(客户端响应Store变化)
通过browser变量限制仅在客户端执行响应Store变化的请求,避免SSR重复执行:
<script> import { dateStore, shiftStore } from '../../../lib/store'; import { browser } from '$app/environment'; // 接收load函数返回的SSR初始数据 export let comments = []; export let areas = []; $: shift = $shiftStore; $: date = $dateStore; async function fetchComments(newDate, newShift) { const dateStr = newDate.toISOString().split('T')[0]; const res = await fetch(`/api/${dateStr}/${newShift}/1`); comments = await res.json(); } async function fetchAreas(newDate, newShift) { const dateStr = newDate.toISOString().split('T')[0]; const res = await fetch(`/api/api/TurnReportArea/1/${dateStr}/${newShift}`); areas = await res.json(); } // 仅在客户端,当date/shift变化时重新请求 $: if (browser && date && shift) { fetchAreas(date, shift); fetchComments(date, shift); } </script>
额外注意事项
- 如果Store的初始值需要从服务器端获取(比如从请求头、Cookie),可以在
hooks.server.js中初始化Store,确保SSR阶段能拿到正确值。 - 不要在load函数中直接订阅Store,因为load只在页面初始加载时执行;客户端的响应式更新交给组件内的
$:语句处理即可。
内容的提问来源于stack exchange,提问作者Avi4nFLu
相关产品推荐
相关产品推荐

