Remix 1.16 如何实现仅从数据库获取一次静态数据?
解决Remix 1.16中静态数据仅获取一次的问题
针对你提到的静态数据(比如选择框选项)每次POST请求都重新从数据库获取的问题,这里有几个可行的解决方案:
方案1:设置Loader的缓存策略(推荐)
Remix允许通过配置响应头或loader缓存选项,让服务器缓存loader的结果,避免重复查询数据库。
修改root的loader,添加缓存配置:
export async function loader({ request }) { const staticData = await getStaticData(request); return json(staticData, { headers: { // 缓存1年,标记为不可变,适配永不变化的数据 "Cache-Control": "public, max-age=31536000, immutable" } }); }
或者使用Remix内置的cache选项(1.16版本支持):
export async function loader({ request }) { const staticData = await getStaticData(request); return json(staticData, { cache: "force-cache" }); }
配置后,后续请求(包括POST后的重定向)会直接使用缓存的结果,无需再次查询数据库。
方案2:服务器端内存缓存
如果你的应用是单实例部署,可以在服务器端用全局变量缓存数据,仅在首次请求时从数据库获取:
// 全局变量存储缓存的静态数据 let cachedStaticData = null; export async function loader({ request }) { if (!cachedStaticData) { cachedStaticData = await getStaticData(request); } return cachedStaticData; }
注意:多实例部署(如负载均衡场景)下,每个实例会各自缓存数据,此时建议改用Redis等分布式缓存替代内存变量。
方案3:客户端独立缓存
在客户端通过自定义Hook获取数据,并存入localStorage或状态中,完全避开root loader的刷新逻辑:
// 自定义Hook:获取并缓存静态数据 export function useStaticData() { const [staticData, setStaticData] = useState(null); useEffect(() => { async function fetchData() { const res = await fetch("/api/static-data"); const data = await res.json(); setStaticData(data); // 存入localStorage实现持久化缓存 localStorage.setItem("staticData", JSON.stringify(data)); } // 优先从localStorage读取缓存 const cached = localStorage.getItem("staticData"); if (cached) { setStaticData(JSON.parse(cached)); } else { fetchData(); } }, []); return staticData; }
同时需要创建一个单独的路由(如app/routes/api/static-data.tsx)提供数据接口:
export async function loader() { return json(await getStaticData()); }
这种方式下,数据仅在客户端首次加载时获取一次,不受任何POST请求影响。
内容的提问来源于stack exchange,提问作者Joao Gui
相关产品推荐
相关产品推荐

