2022-01-03 05:42:17 +00:00
|
|
|
|
//! Suspense in Dioxus
|
|
|
|
|
//!
|
2024-01-16 19:18:46 +00:00
|
|
|
|
//! Currently, `rsx!` does not accept futures as values. To achieve the functionality
|
2022-01-03 05:42:17 +00:00
|
|
|
|
//! of suspense, we need to make a new component that performs its own suspense
|
|
|
|
|
//! handling.
|
|
|
|
|
//!
|
|
|
|
|
//! In this example, we render the `Doggo` component which starts a future that
|
|
|
|
|
//! will cause it to fetch a random dog image from the Dog API. Since the data
|
|
|
|
|
//! is not ready immediately, we render some loading text.
|
|
|
|
|
//!
|
2023-07-25 19:30:08 +00:00
|
|
|
|
//! We can achieve the majority of suspense functionality by composing "suspenseful"
|
2022-01-03 05:42:17 +00:00
|
|
|
|
//! primitives in our own custom components.
|
|
|
|
|
|
2024-01-20 00:36:40 +00:00
|
|
|
|
use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
2022-01-03 05:42:17 +00:00
|
|
|
|
use dioxus::prelude::*;
|
|
|
|
|
|
|
|
|
|
fn main() {
|
2024-10-10 23:00:58 +00:00
|
|
|
|
dioxus::LaunchBuilder::new()
|
2024-03-27 19:08:05 +00:00
|
|
|
|
.with_cfg(desktop! {
|
2024-01-16 14:42:16 +00:00
|
|
|
|
Config::new().with_window(
|
|
|
|
|
WindowBuilder::new()
|
|
|
|
|
.with_title("Doggo Fetcher")
|
|
|
|
|
.with_inner_size(LogicalSize::new(600.0, 800.0)),
|
2024-03-27 19:08:05 +00:00
|
|
|
|
)
|
|
|
|
|
})
|
2024-01-18 20:32:01 +00:00
|
|
|
|
.launch(app)
|
2022-01-03 05:42:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-14 04:51:37 +00:00
|
|
|
|
fn app() -> Element {
|
2024-01-16 19:18:46 +00:00
|
|
|
|
rsx! {
|
2022-01-03 05:42:17 +00:00
|
|
|
|
div {
|
2024-01-16 14:42:16 +00:00
|
|
|
|
h1 { "Dogs are very important" }
|
2022-01-03 05:42:17 +00:00
|
|
|
|
p {
|
2022-02-21 20:39:47 +00:00
|
|
|
|
"The dog or domestic dog (Canis familiaris[4][5] or Canis lupus familiaris[5])"
|
|
|
|
|
"is a domesticated descendant of the wolf which is characterized by an upturning tail."
|
2022-01-03 05:42:17 +00:00
|
|
|
|
"The dog derived from an ancient, extinct wolf,[6][7] and the modern grey wolf is the"
|
|
|
|
|
"dog's nearest living relative.[8] The dog was the first species to be domesticated,[9][8]"
|
2022-01-03 05:46:06 +00:00
|
|
|
|
"by hunter–gatherers over 15,000 years ago,[7] before the development of agriculture.[1]"
|
2022-01-03 05:42:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h3 { "Illustrious Dog Photo" }
|
2024-07-02 03:50:36 +00:00
|
|
|
|
SuspenseBoundary {
|
|
|
|
|
fallback: move |suspense: SuspenseContext| suspense.suspense_placeholder().unwrap_or_else(|| rsx! {
|
|
|
|
|
div {
|
|
|
|
|
"Loading..."
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
Doggo {}
|
|
|
|
|
}
|
2022-01-03 05:42:17 +00:00
|
|
|
|
}
|
2024-01-14 05:12:21 +00:00
|
|
|
|
}
|
2022-01-03 05:42:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// This component will re-render when the future has finished
|
|
|
|
|
/// Suspense is achieved my moving the future into only the component that
|
|
|
|
|
/// actually renders the data.
|
2024-02-14 21:48:58 +00:00
|
|
|
|
#[component]
|
2024-01-14 04:51:37 +00:00
|
|
|
|
fn Doggo() -> Element {
|
2024-07-02 03:50:36 +00:00
|
|
|
|
let mut resource = use_resource(move || async move {
|
2024-01-15 21:06:05 +00:00
|
|
|
|
#[derive(serde::Deserialize)]
|
|
|
|
|
struct DogApi {
|
|
|
|
|
message: String,
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-03 05:42:17 +00:00
|
|
|
|
reqwest::get("https://dog.ceo/api/breeds/image/random/")
|
|
|
|
|
.await
|
|
|
|
|
.unwrap()
|
|
|
|
|
.json::<DogApi>()
|
|
|
|
|
.await
|
|
|
|
|
});
|
|
|
|
|
|
2024-07-02 03:50:36 +00:00
|
|
|
|
// You can suspend the future and only continue rendering when it's ready
|
|
|
|
|
let value = resource.suspend().with_loading_placeholder(|| {
|
|
|
|
|
rsx! {
|
|
|
|
|
div {
|
|
|
|
|
"Loading doggos..."
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})?;
|
|
|
|
|
|
|
|
|
|
match value.read_unchecked().as_ref() {
|
|
|
|
|
Ok(resp) => rsx! {
|
|
|
|
|
button { onclick: move |_| resource.restart(), "Click to fetch another doggo" }
|
2024-01-16 14:42:16 +00:00
|
|
|
|
div { img { max_width: "500px", max_height: "500px", src: "{resp.message}" } }
|
2022-01-03 05:42:17 +00:00
|
|
|
|
},
|
2024-07-02 03:50:36 +00:00
|
|
|
|
Err(_) => rsx! {
|
|
|
|
|
div { "loading dogs failed" }
|
|
|
|
|
button {
|
|
|
|
|
onclick: move |_| resource.restart(),
|
|
|
|
|
"retry"
|
|
|
|
|
}
|
|
|
|
|
},
|
2024-01-14 05:12:21 +00:00
|
|
|
|
}
|
2022-01-03 05:42:17 +00:00
|
|
|
|
}
|