Forráskód Böngészése

Fix suspense on resource

Jonathan Kelley 1 éve
szülő
commit
69e4ebe4ed
3 módosított fájl, 20 hozzáadás és 23 törlés
  1. 7 8
      examples/dog_app.rs
  2. 2 2
      examples/suspense.rs
  3. 11 13
      packages/hooks/src/use_resource.rs

+ 7 - 8
examples/dog_app.rs

@@ -29,7 +29,7 @@ fn app() -> Element {
         }
     });
 
-    let Some(breed_list) = breed_list.value().cloned() else {
+    let Some(breed_list) = breed_list() else {
         return rsx! { "loading breeds..." };
     };
 
@@ -44,7 +44,7 @@ fn app() -> Element {
 
 #[component]
 fn BreedPic(breed: Signal<String>) -> Element {
-    let fut = use_resource(move || async move {
+    let mut fut = use_resource(move || async move {
         reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random"))
             .await
             .unwrap()
@@ -52,14 +52,13 @@ fn BreedPic(breed: Signal<String>) -> Element {
             .await
     });
 
-    match fut.value().read().as_ref() {
+    match fut.read().as_ref() {
         Some(Ok(resp)) => rsx! {
-            div {
-                button { onclick: move |_| fut.restart(), "Click to fetch another doggo" }
-                img { max_width: "500px", max_height: "500px", src: "{resp.message}" }
-            }
+            button { onclick: move |_| fut.restart(), "Click to fetch another doggo" }
+            img { max_width: "500px", max_height: "500px", src: "{resp.message}" }
         },
-        _ => rsx! { "loading image..." },
+        Some(Err(_)) => rsx! { "loading image failed" },
+        None => rsx! { "loading image..." },
     }
 }
 

+ 2 - 2
examples/suspense.rs

@@ -50,7 +50,7 @@ fn app() -> Element {
 /// Suspense is achieved my moving the future into only the component that
 /// actually renders the data.
 fn Doggo() -> Element {
-    let fut = use_future(move || async move {
+    let mut fut = use_resource(move || async move {
         #[derive(serde::Deserialize)]
         struct DogApi {
             message: String,
@@ -63,7 +63,7 @@ fn Doggo() -> Element {
             .await
     });
 
-    match fut.value().read().as_ref() {
+    match fut.read().as_ref() {
         Some(Ok(resp)) => rsx! {
             button { onclick: move |_| fut.restart(), "Click to fetch another doggo" }
             div { img { max_width: "500px", max_height: "500px", src: "{resp.message}" } }

+ 11 - 13
packages/hooks/src/use_resource.rs

@@ -2,7 +2,7 @@
 
 use crate::{use_callback, use_signal, UseCallback};
 use dioxus_core::{
-    prelude::{spawn, suspend, use_hook},
+    prelude::{spawn, use_hook},
     Task,
 };
 use dioxus_signals::*;
@@ -39,7 +39,7 @@ where
 
             // Set the value and state
             state.set(UseResourceState::Ready);
-            value.set(Some(Signal::new(res)));
+            value.set(Some(res));
         })
     });
 
@@ -70,7 +70,7 @@ where
 
 #[allow(unused)]
 pub struct Resource<T: 'static> {
-    value: Signal<Option<Signal<T>>>,
+    value: Signal<Option<T>>,
     task: Signal<Task>,
     state: Signal<UseResourceState>,
     callback: UseCallback<Task>,
@@ -148,17 +148,15 @@ impl<T> Resource<T> {
     }
 
     /// Get the current value of the future.
-    pub fn value(&self) -> Option<ReadOnlySignal<T>> {
-        self.value.peek().as_ref().map(|sig| (*sig).into())
+    pub fn value(&self) -> ReadOnlySignal<Option<T>> {
+        self.value.into()
     }
+}
 
-    /// Wait for this async memo to resolve, returning the inner signal value
-    /// If the value is pending, returns none and suspends the current component
-    pub fn suspend(&self) -> Option<ReadOnlySignal<T>> {
-        let out = self.value.cloned();
-        if out.is_none() {
-            suspend();
-        }
-        out.map(|sig| sig.into())
+impl<T> std::ops::Deref for Resource<T> {
+    type Target = Signal<Option<T>>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.value
     }
 }