Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs-src/0.7/src/essentials/advanced/breaking_out.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ DemoFrame {
}
```

### Returning a Cleanup Closure

You can return a cleanup closure from your `onmounted` handler. This closure runs when the element is removed from the DOM, allowing you to clean up resources like animations, event listeners, or observers:

```rust, no_run
{{#include ../docs-router/src/doc_examples/breaking_out.rs:onmounted_cleanup}}
```
```inject-dioxus
DemoFrame {
breaking_out::OnMountedWithCleanup {}
}
```

This pattern is useful when you need to:
- Stop animations running on an element
- Remove event listeners added to the window or document
- Clear intervals or timeouts
- Disconnect observers (ResizeObserver, IntersectionObserver, etc.)

> The cleanup runs before the element is removed, so you still have access to the DOM state if needed.

## Down casting web sys events

Dioxus provides platform agnostic wrappers over each event type. These wrappers are often nicer to interact with than the raw event types, but they can be more limited. If you are targeting web, you can downcast the event with the `as_web_event` method to get the underlying web-sys event:
Expand Down
19 changes: 19 additions & 0 deletions docs-src/0.7/src/essentials/advanced/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,22 @@ DemoFrame {
component_lifecycle::DropDemo {}
}
```

## Element Cleanup with `onmounted`

While `use_drop` runs when a component is dropped, you can also run cleanup code when a specific element is removed from the DOM. Return a cleanup closure from your `onmounted` handler:

```rust, no_run
div {
onmounted: move |e| {
let el = e.data();
start_animation(el.clone());
// Return cleanup that runs when element is removed
move || stop_animation(el)
},
}
```

This is useful when you need cleanup tied to a specific element's lifetime rather than the whole component. For example, stopping animations on individual elements when they're removed.

See [Breaking Out - onmounted](./breaking_out.md#getting-access-to-elements-with-onmounted) for more details and a full example.
42 changes: 42 additions & 0 deletions packages/docs-router/src/doc_examples/breaking_out.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use dioxus::prelude::*;
pub use downcast::Downcast;
pub use eval::Eval;
pub use onmounted_::OnMounted;
pub use onmounted_cleanup::OnMountedWithCleanup;
pub use use_effect::Canvas;
pub use web_sys::WebSys;

Expand Down Expand Up @@ -143,3 +144,44 @@ mod onmounted_ {
}
// ANCHOR_END: onmounted
}

mod onmounted_cleanup {
use super::*;

// ANCHOR: onmounted_cleanup
pub fn OnMountedWithCleanup() -> Element {
let mut show_element = use_signal(|| true);
let mut status = use_signal(|| "Element not mounted yet".to_string());

rsx! {
div {
button {
onclick: move |_| show_element.toggle(),
if show_element() { "Remove Element" } else { "Add Element" }
}
div { "Status: {status}" }
if show_element() {
div {
class: "p-4 bg-blue-100 rounded mt-2",
onmounted: move |e| {
let el = e.data();
start_animation(el.clone(), status);
// Return a cleanup closure that runs when the element is removed
move || stop_animation(el, status)
},
"Animated element"
}
}
}
}
}

fn start_animation(_el: std::rc::Rc<MountedData>, mut status: Signal<String>) {
status.set("Animation started".to_string());
}

fn stop_animation(_el: std::rc::Rc<MountedData>, mut status: Signal<String>) {
status.set("Animation stopped (cleanup ran)".to_string());
}
// ANCHOR_END: onmounted_cleanup
}