From 48eb65fb1176948bf5946c29a7028881100f8634 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Thu, 14 Apr 2022 22:03:32 +0500 Subject: [PATCH] use_future takes a closure --- packages/yew/src/suspense/hooks.rs | 40 ++++++++++++++++++++++++++---- packages/yew/tests/suspense.rs | 2 +- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/packages/yew/src/suspense/hooks.rs b/packages/yew/src/suspense/hooks.rs index 5c52f0b3fcd..2240a0e21f3 100644 --- a/packages/yew/src/suspense/hooks.rs +++ b/packages/yew/src/suspense/hooks.rs @@ -1,7 +1,9 @@ #[cfg_attr(documenting, doc(cfg(any(target_arch = "wasm32", feature = "tokio"))))] #[cfg(any(target_arch = "wasm32", feature = "tokio"))] mod feat_futures { + use std::fmt; use std::future::Future; + use std::ops::Deref; use yew::prelude::*; use yew::suspense::{Suspension, SuspensionResult}; @@ -10,22 +12,50 @@ mod feat_futures { /// /// A [Suspension] is created from the passed future and the result of the future /// is the output of the suspension. + pub struct UseFutureHandle { + inner: UseStateHandle>, + } + + impl Deref for UseFutureHandle { + type Target = O; + + fn deref(&self) -> &Self::Target { + &*self.inner.as_ref().unwrap() + } + } + + impl fmt::Debug for UseFutureHandle { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("UseFutureHandle") + .field("value", &format!("{:?}", self.inner)) + .finish() + } + } + #[hook] - pub fn use_future(f: F) -> SuspensionResult + pub fn use_future(f: F) -> SuspensionResult> where - T: Clone + 'static, - F: Future + 'static, + F: FnOnce() -> T + 'static, + T: Future + 'static, + O: 'static, { let output = use_state(|| None); let suspension = { let output = output.clone(); - use_state(move || Suspension::from_future(async move { output.set(Some(f.await)) })) + use_memo( + move |_| { + Suspension::from_future(async move { + output.set(Some(f().await)); + }) + }, + (), + ) }; if suspension.resumed() { - Ok((*output).clone().unwrap()) + Ok(UseFutureHandle { inner: output }) } else { Err((*suspension).clone()) } diff --git a/packages/yew/tests/suspense.rs b/packages/yew/tests/suspense.rs index e6a324dcfdb..976f0270bf2 100644 --- a/packages/yew/tests/suspense.rs +++ b/packages/yew/tests/suspense.rs @@ -598,7 +598,7 @@ async fn effects_not_run_when_suspended() { async fn use_suspending_future_works() { #[function_component(Content)] fn content() -> HtmlResult { - let _sleep_handle = use_future(async move { + let _sleep_handle = use_future(|| async move { TimeoutFuture::new(50).await; })?;