Svelte:有没有办法缓存 api 结果,这样就不会在每次组件渲染时触发 api 调用?

问题描述 投票:0回答:3

可能是我在 Google 中输入了错误的内容,无法得到好的答案。

是否有一种“推荐的简洁”方式来存储 GET 结果的值,以便在每次刷新或链接切换时,存储中的结果都在组件中使用,直到超时(再次调用 api)?

我的目的是从外部 API 获取博客文章并将其显示在列表中,但不是在每次刷新或链接切换时显示。

我的代码:

<script>
  let posts = [];

  onMount(async () => {
    const res = await fetch(apiBaseUrl + "/blogposts");
    posts = await res.json();
  });
</script>

{#each posts as post}
  <h5>{post.title}</h5>
{/each}

用伪代码我想要什么:

if (store.blogposts.timeout === true){
  onMount(...);
  // renew component
} 
javascript api caching store svelte
3个回答
15
投票

您可以使用商店来实现这一点。初始页面加载从 api 获取帖子数据并保存在商店中。然后在进一步的页面安装中使用帖子数据。每当您想要刷新数据时,请将超时设置为 true。

./stores.js

import {writable} from 'svelte/store';
export const posts = writable([]);
export const timeout = writable(false);

./posts.svelte

<script>
import {posts, timeout} from "./stores.js"

 onMount(async () => {
   if($posts.length<1 || $timeout == true){
     const res = await fetch(apiBaseUrl + "/blogposts");
     $posts = await res.json();
   }
});
</script>

  {#each $posts as post}
    <h5>{post.title}</h5>
  {/each}

刷新页面时,商店中的帖子将被清除。为了避免这种情况,请使用本地存储来缓存数据。请检查下面的代码。 ./posts.svelte

<script>
let posts = [];
 
onMount(async () => { 
 posts = await getdata();
 } 
 
const getdata = async ()=>{
  // set cache lifetime in seconds
  var cachelife = 5000; 
   //get cached data from local storage
    var cacheddata = localStorage.getItem('posts'); 
    if(cacheddata){
     cacheddata = JSON.parse(cacheddata);
     var expired = parseInt(Date.now() / 1000) - cacheddata.cachetime > cachelife;
      }
    //If cached data available and not expired return them. 
    if (cacheddata  && !expired){
     return cacheddata.posts;
    }else{
    //otherwise fetch data from api then save the data in localstorage 
     const res = await fetch(apiBaseUrl + "/blogposts");
     var posts = await res.json();
     var json = {data: posts, cachetime: parseInt(Date.now() / 1000)}
     localStorage.setItem('posts', JSON.stringify(json));
     return posts;
    }
  }
 
{#each posts as post}
<h5>{post.title}</h5>
{/each}
    

2
投票

svelte-query 可以帮助:

Svelte Query 通常被描述为 Svelte 缺少的数据获取库,但从更技术的角度来说,它使得在 Svelte 应用程序中获取、缓存、同步和更新服务器状态变得轻而易举。

注意:svelte-query 已被废弃,将被替换为@tanstack/svelte-query


0
投票

您可以通过 Sveltekit 的本地存储缓存数据。要清除本地存储,您可以每隔一段时间执行

localStorage.clear()
函数:

  let data;
  let interval;

  onMount(async () => {
    // If data is cached, get it otherwise fetch it
    const cachedData = localStorage.getItem('cachedData');
    if (cachedData) {
      data = JSON.parse(cachedData);
    } else {
      data = await fetch('http://localhost:8080/blogposts')
        .then((response) => response.json())
        .then((dataJson) => dataJson)
        .catch((err) => console.warn(err));
      localStorage.setItem('cachedData', JSON.stringify(data));
    }

    // Clear the local storage after 3 seconds
    interval = setInterval(() => localStorage.clear(), 3000);
  });

可选地,在组件卸载/销毁时清理间隔。通过

clearInterval
函数可以轻松实现:

  onDestroy(() => {
    clearInterval(interval);
  });

我还创建了一个简单的 API 路由来获取。

routes/blogposts/+server.js
文件的内容:

export function GET({ url }) {
  const data = [
    { title: 'Blog post 1', body: 'Body 1' },
    { title: 'Blog post 2', body: 'Body 2' },
    { title: 'Blog post 3', body: 'Body 3' }
  ];

  return new Response(JSON.stringify(data));
}

之后,您可以从 http://localhost:8080/blogposts URL 获取数据。

© www.soinside.com 2019 - 2024. All rights reserved.