sycamore-rs / sycamore

A library for creating reactive web apps in Rust and WebAssembly
https://sycamore-rs.netlify.app
MIT License
2.79k stars 148 forks source link

Console error "closure invoked recursively or after being dropped" when executing `navigate` in a component using `Indexed` #659

Closed ab-honda-ichigo closed 3 weeks ago

ab-honda-ichigo commented 7 months ago

Describe the bug When I run navigate, I get the error "Uncaught Error: closure invoked recursively or after being dropped" in the console. This is reproduced in components using Indexed.

Oddly enough, this error always appears three times in the console, regardless of the number of Indexed items.

This can be avoided by providing an a element inside the li element and giving it the href attribute. However, what I actually want to do is to implement an implementation that changes the destination according to the condition when the element is clicked, so I think it is necessary to use navigate.

To Reproduce Below is the source code that this reproduces.

#[component]
pub async fn PopoverMenu<G: Html>() -> View<G>
{
    let items = create_signal(vec!["hoge", "fuga", "piyo"]);
    view!
    {
        ul
        {
            Indexed
            (
                iterable=*items,
                view=move |_|
                {
                    view!
                    {
                        li
                        (
                            on:click=move |_|
                            {
                                navigate("/");
                            },
                        )
                        {
                            "hoge"
                        }
                    }
                }
            )
        }
    }
}

Screenshots Screenshot_20240303_165916

Environment

Additional context I found #433 as a similar issue.

ichigo-dev commented 7 months ago

Sorry, I'm the poster of this issue. I posted with the wrong user, so I'll add a comment to receive a notification.

lukechu10 commented 7 months ago

The issue has something to do with the fact that the element is removed when the event handler is executed. When the element is removed, the event handler is dropped while it is running! It is indeed the same issue as #443 #433 but I think we can leave this open since it provides a good test case for it.

Edit: referenced wrong issue.

ichigo-dev commented 7 months ago

Thank you for your detailed explanation. Sorry for the trivial point, but the related issue is #433, not #443.

lukechu10 commented 3 weeks ago

I can't seem to reproduce this issue anymore in v0.9.0-beta.3. Here is the complete code listing that I used:

Details

```rust use sycamore::prelude::*; use sycamore_router::{navigate, HistoryIntegration, Route, Router}; #[component] pub async fn PopoverMenu() -> View { let items = create_signal(vec!["hoge", "fuga", "piyo"]); view! { ul { Indexed( list=items, view=move |_| view! { li(on:click=move |_| navigate("/")) { "hoge" } } ) } } } #[derive(Debug, Clone, Copy, Route)] enum AppRoutes { #[to("/")] Index, #[to("/about")] About, #[not_found] NotFound, } #[component] fn App() -> View { view! { Router( integration=HistoryIntegration::new(), view=|route: ReadSignal| { view! { (match route.get() { AppRoutes::Index => view! { "index" }, AppRoutes::About => view! { "about" PopoverMenu() }, AppRoutes::NotFound => view! { "not found" }, }) } }, ) } } fn main() { console_error_panic_hook::set_once(); sycamore::render(App); console_log!("App mounted!"); } ```

If this issue is not fixed for you, please feel free to reopen this issue or create a new issue.