Expand description
§dioxus-query 🦀⚡
Fully-typed, async, reusable cached state management for Dioxus 🧬. Inspired by TanStack Query
.
See the Docs or join the Discord.
§Support
§Features
- Renderer-agnostic
- Queries and Mutations
- Fully typed, no type erasing
- Invalidate queries manually
- Invalidate queries on equality change
- Concurrent execution of queries
- Background interval re-execution of queries
- Opt-in in-memory cache of queries results
-
Works with ReactiveContext-powered hooks like
use_effect
oruse_memo
- On window/tab focus invalidation
§Installation
Install the latest release:
cargo add dioxus-query
§Example
Run manually:
cargo run --example hello_world
Code:
#[derive(Clone)]
struct FancyClient;
impl FancyClient {
pub fn name(&self) -> &'static str {
"Marc"
}
}
#[derive(Clone, PartialEq, Hash, Eq)]
struct GetUserName(Captured<FancyClient>);
impl QueryCapability for GetUserName {
type Ok = String;
type Err = ();
type Keys = usize;
async fn run(&self, user_id: &Self::Keys) -> Result<Self::Ok, Self::Err> {
println!("Fetching name of user {user_id}");
sleep(Duration::from_millis(650)).await;
match user_id {
0 => Ok(self.0.name().to_string()),
_ => Err(()),
}
}
}
#[allow(non_snake_case)]
#[component]
fn User(id: usize) -> Element {
let user_name = use_query(Query::new(id, GetUserName(Captured(FancyClient))));
rsx!(
p { "{user_name.read().state():?}" }
)
}
fn app() -> Element {
let refresh = move |_| async move {
QueriesStorage::<GetUserName>::invalidate_matching(0).await;
};
rsx!(
User { id: 0 }
User { id: 0 }
button { onclick: refresh, label { "Refresh" } }
)
}
§To Do
- Tests
- Improved documentation
- Real-world examples
MIT License