2 unstable releases

new 0.2.0 Mar 13, 2025
0.1.0 Mar 12, 2025

#50 in Caching

MIT license

92KB
2K SLoC

Leptos Fetch

github crates.io docs.rs

About

Leptos Fetch is a async state management library for Leptos.

The successor of, and heavily inspired by Leptos Query, which has been unmaintained for ~1 year.

Queries are useful for data fetching, caching, and synchronization with server state.

This crate provides:

  • Caching
  • Request de-duplication
  • Invalidation
  • Background refetching
  • Refetch intervals
  • Memory management with cache lifetimes
  • Cancellation
  • Debugging tools
  • Optimistic updates
  • Client side cache persistance (localstorage, indexdb, custom, etc.)

Lines that have a strike through are features not currently brought over from Leptos Query.

Feature Flags

  • ssr Server-side rendering: Initiate queries on the server.

Version compatibility for Leptos and Leptos Fetch

The table below shows the compatible versions of leptos-fetch for each leptos version. Ensure you are using compatible versions to avoid potential issues.

leptos version leptos-fetch version
0.7.* 0.1.* 0.2.*

Installation

cargo add leptos-fetch

If using ssr, add the relevant feature to your Cargo.toml when in ssr:

[features]
ssr = [
    "leptos-fetch/ssr",
    # ...
 ]

Quick Start

In the root of your App, provide a query client with [QueryClient::provide()] or [QueryClient::provide_with_options()] if you want to override the default options.

use leptos::prelude::*;
use leptos_fetch::QueryClient;

#[component]
pub fn App() -> impl IntoView {
    // Provides the Query Client for the entire app via leptos context.
    QueryClient::provide();
    
    // QueryClient::provide_with_options(QueryOptions::new()..) can customize default caching behaviour.

    // Rest of App...
}

Any async function can be used as a query:

/// The query function.
async fn get_track(id: i32) -> String {
    todo!()
}

Now you can use the query in any component in your app.

use leptos::prelude::*;
use leptos_fetch::QueryClient;

#[component]
fn TrackView(id: i32) -> impl IntoView {
    // Usually at the root of the App:
    QueryClient::provide();

    // Extract the root client from leptos context,
    // this is identical to expect_context::<QueryClient>()
    let client = QueryClient::expect();
    
    // Native leptos resources are returned, 
    // there are also variants for local, blocking, arc resources. 
    let resource = client.resource(get_track, move || id.clone());

    view! {
       <div>
           // Resources can be awaited inside a Transition/Suspense components.
           // Alternative .read()/.get()/.with() etc can be used synchronously returning Option's.
           <Transition
               fallback=move || {
                   view! { <h2>"Loading..."</h2> }
               }>
                {move || Suspend::new(async move {
                    let track = resource.await;
                    view! { <h2>{track}</h2> }
                })}          
           </Transition>
       </div>
    }
}

/// The query function.
async fn get_track(id: i32) -> String {
    todo!()
}

You can read more about leptos resources in the Leptos Book

QueryScope and QueryScopeLocal can be used instead of directly passing a function to QueryClient methods to only apply to one query type.

These QueryOptions will be combined with the global QueryOptions set on the crate::QueryClient, with the local options taking precedence.

use std::time::Duration;
use leptos_fetch::{QueryScope, QueryOptions};

// this can be used just like the function directly in QueryClient methods.
fn track_query() -> QueryScope<i32, String> {
    QueryScope::new(
        get_track, 
        QueryOptions::new()
            .set_stale_time(Duration::from_secs(10))
            .set_gc_time(Duration::from_secs(60))
    )
}

/// The query function.
async fn get_track(id: i32) -> String {
    todo!()
}

The QueryClient contains many documented utility methods other than resources for:

  • Declaratively fetching queries
  • Declaratively prefetching queries
  • Mutating cached queries
  • Invalidating cached queries
  • Accessing cached queries

Dependencies

~25–38MB
~587K SLoC