1
0

suspense.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //! Suspense in Dioxus
  2. //!
  3. //! Currently, `rsx!` does not accept futures as values. To achieve the functionality
  4. //! of suspense, we need to make a new component that performs its own suspense
  5. //! handling.
  6. //!
  7. //! In this example, we render the `Doggo` component which starts a future that
  8. //! will cause it to fetch a random dog image from the Dog API. Since the data
  9. //! is not ready immediately, we render some loading text.
  10. //!
  11. //! We can achieve the majoirty of suspense functionality by composing "suspenseful"
  12. //! primitives in our own custom components.
  13. use dioxus::prelude::*;
  14. fn main() {
  15. use dioxus::desktop::tao::dpi::LogicalSize;
  16. dioxus::desktop::launch_cfg(app, |cfg| {
  17. cfg.with_window(|w| {
  18. w.with_title("Doggo Fetcher")
  19. .with_inner_size(LogicalSize::new(600.0, 800.0))
  20. })
  21. });
  22. }
  23. #[derive(serde::Deserialize)]
  24. struct DogApi {
  25. message: String,
  26. }
  27. fn app(cx: Scope) -> Element {
  28. cx.render(rsx! {
  29. div {
  30. h1 {"Dogs are very important"}
  31. p {
  32. "The dog or domestic dog (Canis familiaris[4][5] or Canis lupus familiaris[5])"
  33. "is a domesticated descendant of the wolf which is characterized by an upturning tail."
  34. "The dog derived from an ancient, extinct wolf,[6][7] and the modern grey wolf is the"
  35. "dog's nearest living relative.[8] The dog was the first species to be domesticated,[9][8]"
  36. "by hunter–gatherers over 15,000 years ago,[7] before the development of agriculture.[1]"
  37. }
  38. h3 { "Illustrious Dog Photo" }
  39. Doggo { }
  40. }
  41. })
  42. }
  43. /// This component will re-render when the future has finished
  44. /// Suspense is achieved my moving the future into only the component that
  45. /// actually renders the data.
  46. fn Doggo(cx: Scope) -> Element {
  47. let fut = use_future(&cx, || async move {
  48. reqwest::get("https://dog.ceo/api/breeds/image/random/")
  49. .await
  50. .unwrap()
  51. .json::<DogApi>()
  52. .await
  53. });
  54. cx.render(match fut.value() {
  55. Some(Ok(resp)) => rsx! {
  56. button {
  57. onclick: move |_| fut.restart(),
  58. "Click to fetch another doggo"
  59. }
  60. div {
  61. img {
  62. max_width: "500px",
  63. max_height: "500px",
  64. src: "{resp.message}",
  65. }
  66. }
  67. },
  68. Some(Err(_)) => rsx! { div { "loading dogs failed" } },
  69. None => rsx! { div { "loading dogs..." } },
  70. })
  71. }