diff --git a/CHANGELOG.md b/CHANGELOG.md index 43a5e4c..20fe0dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.11.3] - 2024-07-31 + +### Fix 🍕 + +- Made `use_timeout_fn` SSR-safe + ## [0.11.2] - 2024-07-30 ### Change 🔥 diff --git a/Cargo.toml b/Cargo.toml index 1201482..24e568a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leptos-use" -version = "0.11.2" +version = "0.11.3" edition = "2021" authors = ["Marc-Stefan Cassola"] categories = ["gui", "web-programming"] diff --git a/src/use_timeout_fn.rs b/src/use_timeout_fn.rs index 7ae644b..2e3d27f 100644 --- a/src/use_timeout_fn.rs +++ b/src/use_timeout_fn.rs @@ -1,9 +1,5 @@ -use leptos::leptos_dom::helpers::TimeoutHandle; use leptos::*; -use std::cell::Cell; use std::marker::PhantomData; -use std::rc::Rc; -use std::time::Duration; /// Wrapper for `setTimeout` with controls. /// @@ -31,6 +27,11 @@ use std::time::Duration; /// # view! { } /// # } /// ``` +/// +/// ## Server-Side Rendering +/// +/// On the server the callback will never be run. The returned functions are all no-ops and +/// `is_pending` will always be `false`. pub fn use_timeout_fn( callback: CbFn, delay: D, @@ -40,65 +41,86 @@ where Arg: 'static, D: Into>, { - let delay = delay.into(); - let (is_pending, set_pending) = create_signal(false); - let timer = Rc::new(Cell::new(None::)); + let start; + let stop; - let clear = { - let timer = Rc::clone(&timer); + #[cfg(not(feature = "ssr"))] + { + use leptos::leptos_dom::helpers::TimeoutHandle; + use std::cell::Cell; + use std::rc::Rc; + use std::time::Duration; - move || { - if let Some(timer) = timer.take() { - timer.clear(); + let delay = delay.into(); + + let timer = Rc::new(Cell::new(None::)); + + let clear = { + let timer = Rc::clone(&timer); + + move || { + if let Some(timer) = timer.take() { + timer.clear(); + } } - } - }; + }; - let stop = { - let clear = clear.clone(); + stop = { + let clear = clear.clone(); - move || { - set_pending.set(false); - clear(); - } - }; + move || { + set_pending.set(false); + clear(); + } + }; - let start = { - let timer = Rc::clone(&timer); - let callback = callback.clone(); + start = { + let timer = Rc::clone(&timer); + let callback = callback.clone(); - move |arg: Arg| { - set_pending.set(true); + move |arg: Arg| { + set_pending.set(true); - let handle = set_timeout_with_handle( - { - let timer = Rc::clone(&timer); - let callback = callback.clone(); + let handle = set_timeout_with_handle( + { + let timer = Rc::clone(&timer); + let callback = callback.clone(); - move || { - set_pending.set(false); - timer.set(None); + move || { + set_pending.set(false); + timer.set(None); - #[cfg(debug_assertions)] - let prev = SpecialNonReactiveZone::enter(); + #[cfg(debug_assertions)] + let prev = SpecialNonReactiveZone::enter(); - callback(arg); + callback(arg); - #[cfg(debug_assertions)] - SpecialNonReactiveZone::exit(prev); - } - }, - Duration::from_millis(delay.get_untracked() as u64), - ) - .ok(); + #[cfg(debug_assertions)] + SpecialNonReactiveZone::exit(prev); + } + }, + Duration::from_millis(delay.get_untracked() as u64), + ) + .ok(); - timer.set(handle); - } - }; + timer.set(handle); + } + }; - on_cleanup(clear); + on_cleanup(clear); + } + + #[cfg(feature = "ssr")] + { + let _ = set_pending; + let _ = callback; + let _ = delay; + + start = move |_: Arg| (); + stop = move || (); + } UseTimeoutFnReturn { is_pending: is_pending.into(),