From 62196ff6389aaff04c626813ae91c39d90d1c963 Mon Sep 17 00:00:00 2001 From: Thomas Versteeg Date: Sat, 11 Jan 2025 03:23:08 +0700 Subject: [PATCH] docs: warn about callbacks outside the ownership tree (#3442) --- leptos_dom/src/helpers.rs | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/leptos_dom/src/helpers.rs b/leptos_dom/src/helpers.rs index 7ad447b8d4..57477271bc 100644 --- a/leptos_dom/src/helpers.rs +++ b/leptos_dom/src/helpers.rs @@ -131,6 +131,10 @@ impl AnimationFrameRequestHandle { /// Runs the given function between the next repaint using /// [`Window.requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame). +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr(feature = "tracing", instrument(level = "trace", skip_all))] #[inline(always)] pub fn request_animation_frame(cb: impl FnOnce() + 'static) { @@ -159,6 +163,10 @@ fn closure_once(cb: impl FnOnce() + 'static) -> JsValue { /// Runs the given function between the next repaint using /// [`Window.requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame), /// returning a cancelable handle. +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr(feature = "tracing", instrument(level = "trace", skip_all))] #[inline(always)] pub fn request_animation_frame_with_handle( @@ -197,6 +205,10 @@ impl IdleCallbackHandle { /// Queues the given function during an idle period using /// [`Window.requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestIdleCallback). +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr(feature = "tracing", instrument(level = "trace", skip_all))] #[inline(always)] pub fn request_idle_callback(cb: impl Fn() + 'static) { @@ -206,6 +218,10 @@ pub fn request_idle_callback(cb: impl Fn() + 'static) { /// Queues the given function during an idle period using /// [`Window.requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestIdleCallback), /// returning a cancelable handle. +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr(feature = "tracing", instrument(level = "trace", skip_all))] #[inline(always)] pub fn request_idle_callback_with_handle( @@ -239,6 +255,8 @@ pub fn request_idle_callback_with_handle( /// to perform final cleanup or other just-before-rendering tasks. /// /// [MDN queueMicrotask](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask) +/// +///
The task is called outside of the ownership tree, this means that if you want to access for example the context you need to reestablish the owner.
pub fn queue_microtask(task: impl FnOnce() + 'static) { use js_sys::{Function, Reflect}; @@ -265,6 +283,10 @@ impl TimeoutHandle { /// Executes the given function after the given duration of time has passed. /// [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout). +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr( feature = "tracing", instrument(level = "trace", skip_all, fields(duration = ?duration)) @@ -275,6 +297,10 @@ pub fn set_timeout(cb: impl FnOnce() + 'static, duration: Duration) { /// Executes the given function after the given duration of time has passed, returning a cancelable handle. /// [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout). +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr( feature = "tracing", instrument(level = "trace", skip_all, fields(duration = ?duration)) @@ -331,6 +357,10 @@ pub fn set_timeout_with_handle( /// } /// } /// ``` +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). pub fn debounce( delay: Duration, mut cb: impl FnMut(T) + 'static, @@ -398,6 +428,10 @@ impl IntervalHandle { /// Repeatedly calls the given function, with a delay of the given duration between calls. /// See [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval). +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr( feature = "tracing", instrument(level = "trace", skip_all, fields(duration = ?duration)) @@ -409,6 +443,10 @@ pub fn set_interval(cb: impl Fn() + 'static, duration: Duration) { /// Repeatedly calls the given function, with a delay of the given duration between calls, /// returning a cancelable handle. /// See [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval). +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr( feature = "tracing", instrument(level = "trace", skip_all, fields(duration = ?duration)) @@ -451,6 +489,10 @@ pub fn set_interval_with_handle( /// Adds an event listener to the `Window`, typed as a generic `Event`, /// returning a cancelable handle. +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). #[cfg_attr( feature = "tracing", instrument(level = "trace", skip_all, fields(event_name = %event_name)) @@ -519,6 +561,10 @@ pub fn window_event_listener_untyped( /// on_cleanup(move || handle.remove()); /// } /// ``` +/// +/// ### Note about Context +/// +/// The callback is called outside of the reactive ownership tree. This means that it does not have access to context via [`use_context`](reactive_graph::owner::use_context). If you want to use context inside the callback, you should either call `use_context` in the body of the component, and move the value into the callback, or access the current owner inside the component body using [`Owner::current`](reactive_graph::owner::Owner::current) and reestablish it in the callback with [`Owner::with`](reactive_graph::owner::Owner::with). pub fn window_event_listener( event: E, cb: impl Fn(E::EventType) + 'static,