1
0

suspense.rs 2.6 KB

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