简体   繁体   中英

Svelte: is there a way to cache the api result in a way that it won't trigger the api call everytime the component renders?

It could be that I'm typing the wrong things in Google and can't get a good answer.

Is there a "svelte recommended" way to store the value of a GET result, so that, on every refresh or link switch, the result in the store is used in the component until a timeout (where the api is called again)?

my purpose is to fetch blogposts from external api and show them in a list but not on every refresh, or link switch

my code:

<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}

in pseudocode what i want

if(store.blogposts.timeout === true){
  onMount(...);
  //renew component
} 

you can use stores to achieve this. Initial page load fetch posts data from api and save in stores. Then use the posts data in further page mounts. Set timeout to true whenever you want to refresh data.

./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}

When you refresh the page the posts in stores will clear. To avoid that use localstorage to cache data. pls check the below code. ./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}
    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM