DioxusLabs / dioxus

Fullstack app framework for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
21.41k stars 826 forks source link

enhancement: Implement memoization by value of `Element`s passed as props #1929

Open marc2332 opened 8 months ago

marc2332 commented 8 months ago

Problem

When a component re runs and is passing an Element to another component, this other component will always rerun, because Dioxus can't seem to be able to memoize Elements.

fn app() -> Element {
    let mut show = use_signal(|| false);

    println!("Why am I running?");

    rsx!(
        div {
            onclick: move |_| {
                *show.write() = true;
            },
            p { "{show}" }
            Whatever {
                div { }
            }
        }
    )
}

#[allow(non_snake_case)]
#[component]
fn Whatever(children: Element) -> Element {

    println!("Why me too?");

    rsx!(
        div {
            {children}
        }
    )
}

Steps To Reproduce

Steps to reproduce the behavior:

Expected behavior

Only println!("Why am I running?"); should run when the parent component re-runs if the passed children are still the same, right?

Screenshots

If applicable, add screenshots to help explain your problem.

Environment:

ealmloff commented 8 months ago

This is expected behavior. VNodes currently implement partialeq by pointer. They could implement a deeper partialEq if the pointers are different, but the current behavior is pretty similar to what you would get with borrowed props with an Element in 0.4

marc2332 commented 8 months ago

🏃

jkelleyrtp commented 3 months ago

We could attempt to diff them with a slightly deeper comparison