From 645e99b8d015ac0d609f9a6c9199d030d7d3a247 Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Thu, 15 Sep 2022 20:52:10 +0900 Subject: [PATCH 1/4] Restore a behaviour of destroy upon unmount. --- packages/yew/src/html/component/lifecycle.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/yew/src/html/component/lifecycle.rs b/packages/yew/src/html/component/lifecycle.rs index 9bde886f4d4..67ad626c4bf 100644 --- a/packages/yew/src/html/component/lifecycle.rs +++ b/packages/yew/src/html/component/lifecycle.rs @@ -403,6 +403,15 @@ impl ComponentState { let _ = parent_to_detach; } } + + if let Some(m) = self.suspension.take() { + let comp_scope = self.inner.any_scope(); + + let suspense_scope = comp_scope.find_parent_scope::().unwrap(); + let suspense = suspense_scope.get_component().unwrap(); + + suspense.resume(m); + } } } From 1e2c1dbad1affc6b86a787b6dacb486c2c2158b0 Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Thu, 15 Sep 2022 20:59:27 +0900 Subject: [PATCH 2/4] Add a test. --- packages/yew/tests/suspense.rs | 52 +++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/packages/yew/tests/suspense.rs b/packages/yew/tests/suspense.rs index 969cc5fcbf6..1717d8a22e6 100644 --- a/packages/yew/tests/suspense.rs +++ b/packages/yew/tests/suspense.rs @@ -8,9 +8,9 @@ use std::time::Duration; use common::obtain_result; use wasm_bindgen::JsCast; -use wasm_bindgen_futures::spawn_local; use wasm_bindgen_test::*; use web_sys::{HtmlElement, HtmlTextAreaElement}; +use yew::platform::spawn_local; use yew::platform::time::sleep; use yew::prelude::*; use yew::suspense::{use_future, use_future_with_deps, Suspension, SuspensionResult}; @@ -684,3 +684,53 @@ async fn use_suspending_future_with_deps_works() { let result = obtain_result(); assert_eq!(result.as_str(), r#"
42
"#); } + +#[wasm_bindgen_test] +async fn test_suspend_forever() { + /// A component that its suspension never resumes. + /// We test that this can be used with to trigger a suspension and unsuspend upon unmount. + #[function_component] + fn SuspendForever() -> HtmlResult { + let (s, handle) = Suspension::new(); + use_state(move || handle); + Err(s) + } + + #[function_component] + fn App() -> Html { + let page = use_state(|| 1); + + { + let page_setter = page.setter(); + use_effect_with_deps( + move |_| { + spawn_local(async move { + sleep(Duration::from_secs(1)).await; + page_setter.set(2); + }); + }, + (), + ); + } + + let content = if *page == 1 { + html! { } + } else { + html! {

{"Page 2"}

} + }; + + html! { + {"Loading..."}}}> + {content} + + } + } + + yew::Renderer::::with_root(gloo::utils::document().get_element_by_id("output").unwrap()) + .render(); + + sleep(Duration::from_millis(1500)).await; + + let result = obtain_result(); + assert_eq!(result.as_str(), r#"

Page 2

"#); +} From 556d3abd44584473dd9183e7a58d997fb5ced9dd Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Thu, 15 Sep 2022 21:10:10 +0900 Subject: [PATCH 3/4] Fix CI. --- packages/yew/tests/suspense.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/yew/tests/suspense.rs b/packages/yew/tests/suspense.rs index 1717d8a22e6..e207dcb02a9 100644 --- a/packages/yew/tests/suspense.rs +++ b/packages/yew/tests/suspense.rs @@ -693,7 +693,7 @@ async fn test_suspend_forever() { fn SuspendForever() -> HtmlResult { let (s, handle) = Suspension::new(); use_state(move || handle); - Err(s) + Err(s.into()) } #[function_component] @@ -714,7 +714,7 @@ async fn test_suspend_forever() { } let content = if *page == 1 { - html! { } + html! { } } else { html! {

{"Page 2"}

} }; From 9aced410f9034fd2e3896d2324a7498975df9c6a Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Thu, 15 Sep 2022 21:24:24 +0900 Subject: [PATCH 4/4] Fix CI. --- packages/yew/src/html/component/lifecycle.rs | 30 +++++++++----------- packages/yew/tests/suspense.rs | 4 +-- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/packages/yew/src/html/component/lifecycle.rs b/packages/yew/src/html/component/lifecycle.rs index 67ad626c4bf..fca8ee27b7c 100644 --- a/packages/yew/src/html/component/lifecycle.rs +++ b/packages/yew/src/html/component/lifecycle.rs @@ -297,6 +297,17 @@ impl ComponentState { .downcast_ref::>() .map(|m| &m.component) } + + fn resume_existing_suspension(&mut self) { + if let Some(m) = self.suspension.take() { + let comp_scope = self.inner.any_scope(); + + let suspense_scope = comp_scope.find_parent_scope::().unwrap(); + let suspense = suspense_scope.get_component().unwrap(); + + suspense.resume(m); + } + } } pub(crate) struct CreateRunner { @@ -370,6 +381,7 @@ impl ComponentState { )] fn destroy(mut self, parent_to_detach: bool) { self.inner.destroy(); + self.resume_existing_suspension(); match self.render_state { #[cfg(feature = "csr")] @@ -403,15 +415,6 @@ impl ComponentState { let _ = parent_to_detach; } } - - if let Some(m) = self.suspension.take() { - let comp_scope = self.inner.any_scope(); - - let suspense_scope = comp_scope.find_parent_scope::().unwrap(); - let suspense = suspense_scope.get_component().unwrap(); - - suspense.resume(m); - } } } @@ -488,14 +491,7 @@ impl ComponentState { fn commit_render(&mut self, shared_state: &Shared>, new_root: Html) { // Currently not suspended, we remove any previous suspension and update // normally. - if let Some(m) = self.suspension.take() { - let comp_scope = self.inner.any_scope(); - - let suspense_scope = comp_scope.find_parent_scope::().unwrap(); - let suspense = suspense_scope.get_component().unwrap(); - - suspense.resume(m); - } + self.resume_existing_suspension(); match self.render_state { #[cfg(feature = "csr")] diff --git a/packages/yew/tests/suspense.rs b/packages/yew/tests/suspense.rs index e207dcb02a9..0183413f796 100644 --- a/packages/yew/tests/suspense.rs +++ b/packages/yew/tests/suspense.rs @@ -716,7 +716,7 @@ async fn test_suspend_forever() { let content = if *page == 1 { html! { } } else { - html! {

{"Page 2"}

} + html! {
{"OK"}
} }; html! { @@ -732,5 +732,5 @@ async fn test_suspend_forever() { sleep(Duration::from_millis(1500)).await; let result = obtain_result(); - assert_eq!(result.as_str(), r#"

Page 2

"#); + assert_eq!(result.as_str(), r#"OK"#); }