ConsoleTVs / sswr

🔥 Svelte stale while revalidate (SWR) data fetching strategy
MIT License
243 stars 12 forks source link
fetch javascript stale-while-revalidate svelte swr typescript

SSWR (Svelte Stale While Revalidate)

Svelte stale while revalidate (SWR) data fetching strategy

Table of Contents

Introduction

Quote from vercel's SWR for react:

The name “SWR” is derived from stale-while-revalidate, a HTTP cache invalidation strategy popularized by HTTP RFC 5861. SWR is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.

With SWR, components will get a stream of data updates constantly and automatically. And the UI will be always fast and reactive.

Features

Installation

You can use npm or yarn to install it.

npm i sswr
yarn add sswr

Getting Started

<script>
  import { useSWR } from "sswr";
  // Call the `useSWR` and pass the key you want to use. It will be pased
  // to the fetcher function. The fetcher function can be configured globally
  // or passed as one of the options to this function.
  const { data: posts } = useSWR("https://jsonplaceholder.typicode.com/posts");
</script>

{#if $posts}
  {#each $posts as post (post.id)}
    <h1>{post.title}</h1>
    <p>{post.body}</p>
  {/each}
{/if}

This is a simple example that will use SWR as the strategy to fetch the data. In this particular case, all the default options are used (or the ones specified in the global config) and it will fetch the data using the default or global fetcher and update the DOM when the request is done.

Configuration options

All hook calls can have their respective configuration options applied to it. Nevertheless you can also configure global options to avoid passing them to each hook call.

Signature

function useSWR(key, options): SWRResponse
// Can be destructured to get the response as such:
const { data, error, mutate, revalidate } = useSWR(key, options)

Parameters

Return Values

Global configuration options

You can configure the options globally by creating a SWR instance and using it in your svelte application. This step is not mandatory but it's recommended for most apps.

You can either choose to manually create a SWR instance and import it when needed or replace the default SWR instance used by all exported APIs. The second is recommended if only one instance will be needed for your application.

Signature

function createSWR(options): VSWR
function createDefaultSWR(options): VSWR

Parameters

Return value

A SWR instance that can be used to access all the API.

Dependent fetching

<script>
  import { useSWR } from "sswr";

  const { data: post } = useSWR("https://jsonplaceholder.typicode.com/posts/1");
  // We need to pass a function as the key. Function will throw an error when post is undefined
  // but we catch that and wait till it re-validates into a valid key to populate the user variable.
  $: ({ data: user } = useSWR(
    () => `https://jsonplaceholder.typicode.com/users/${$post.userId}`
  ));
</script>

{#if $post}
  <div>{$post.title}</div>
{/if}
{#if $user}
  <div>{$user.name}</div>
{/if}

Re-validate on demand

Global revalidate function with given key

You can re-validate specific keys by importing the revalidate function.

import { revalidate } from 'sswr'

You can call this method anywhere in your application by giving it the key, and the options.

Signature

function revalidate(key, options): void
Parameters

On specific hooks with keys

You can re-validate specific keys by grabing the revalidate function of the useSWR call. This function will allow you to perform a re-validation of the data on demand. There's no need to provide the key for this function since it's already bound to the hook key. It only accepts the options.

Signature

function revalidate(options): void
Parameters

Example

<script>
  import { useSWR } from 'sswr'

  const { data: post, revalidate } = useSWR('https://jsonplaceholder.typicode.com/posts/1')
</script>

{#if $post}
  <div>{$post.title}</div>
  <button on:click={() => revalidate()}>Revalidate</button>
{/if}

Mutate on demand

Global mutate function with given key

You can mutate specific keys by importing the mutate function.

import { mutate } from 'sswr'

You can call this method anywhere in your application by giving it the key, the value and the options.

Signature

function mutate(key, value, options): void
Parameters

On specific hooks with keys

You can mutate specific keys by grabing the mutate function of the useSWR call. This function will allow you to perform a mutation of the data on demand. There's no need to provide the key for this function since it's already bound to the hook key. It only accepts the value and the options.

Signature

function mutate(value, options): void
Parameters

Example

Keep in mind we set revalidate to false to avoid it performing a HTTP request for this example, since this would just over-write the static data with the server data again.

<script>
  import { useSWR } from 'sswr'

  const { data: post, mutate } = useSWR('https://jsonplaceholder.typicode.com/posts/1')
</script>

{#if $post}
  <div>{$post.title}</div>
  <button on:click={() => mutate((state) => ({ ...state, title: 'Sample' }), { revalidate: false })}>
    Mutate only title
  </button>
  <button on:click={() => mutate({ title: 'Sample' }, { revalidate: false })}>
    Leave only title
  </button>
{/if}

Error handling

You can handle request errors by using the error return value on a hook call. This will return the specific error that happened to the hook. For example, a failed request.

Example

<script>
  import { useSWR } from 'sswr'

  const { data: posts, error } = useSWR('https://jsonplaceholder.typicode.com/posts')
</script>

{#if $error}
  <div>There was an error</div>
{:else if $posts}
 {#each $posts as post (post.id)}
    <h1>{post.title}</h1>
 {/each}
{/if}

Clear Cache

Global clear function with given keys

You can clear all the cached keys or the specified ones when you need to invalidate some keys.

To do this, you can use the clear global function.

import { clear } from 'sswr'

Signature

function clear(keys, options): void
Parameters

On specific hooks with keys

You can clear specific keys by grabing the clear function of the useSWR call. This function will allow you to clear the data on demand. There's no need to provide the key for this function since it's already bound to the hook key. It only accepts the options.

Signature

function clear(options): void
Parameters

Example

<script>
  import { useSWR } from 'sswr'

  const { data: post, clear } = useSWR('https://jsonplaceholder.typicode.com/posts/1')
</script>

{#if $post}
  <div>{$post.title}</div>
  <button on:click={() => clear()}>
    Clear cacheed data
  </button>
{/if}

Using with SvelteKit SSR

SvelteKit allows you to fetch data on the backend. This allows you to combine SSR (where your data is present in the HTML) with the live updating that this package provides.

Here is an example of how to implement the Getting Started example with support for SSR. In this example, we have disabled the revalidation on the client, althought it is also possible to re-hydrate the information on it if needed.

<script lang="ts" context="module">
  import type { Load } from '@sveltejs/kit';

  const url = 'https://jsonplaceholder.typicode.com/posts';

  export const load: Load = async ({ fetch }) => {
    const response = await fetch(url);

    return {
      props: {
        initialData: await response.json()
      }
    };
  };
</script>

<script lang="ts">
  import { useSWR } from 'sswr';

  interface Post {
    id: number;
    title: string;
    body: string;
  }

  export let initialData: Post[];

  const { data: posts } = useSWR<Post[]>(url, {
    initialData,
    revalidateOnStart: false
  });
</script>

{#if $posts}
  {#each $posts as post (post.id)}
    <h1>{post.title}</h1>
    <p>{post.body}</p>
  {/each}
{/if}

Contributors