Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diffing bug #2324

Open
3 tasks
elias098 opened this issue Apr 17, 2024 · 2 comments
Open
3 tasks

Diffing bug #2324

elias098 opened this issue Apr 17, 2024 · 2 comments
Labels
core relating to the core implementation of the virtualdom

Comments

@elias098
Copy link

Problem

https://discord.com/channels/899851952891002890/943190605067079712/1229957121496580197

With the below code it recreates the ListTest component when ListTest2 goes back to its initial state.
As in if it started with a % 3 == 0 then it recreates it every time a % 3 == 0

Steps To Reproduce

use dioxus::prelude::*;

#[component]
pub fn App() -> Element {
    let mut b = use_signal(|| 0);

    rsx! {
        ListTest2 {
            a: b()
        }
        button {
            onclick: move |_| b += 1,
            "+"
        }
        button {
            onclick: move |_| b -= 1,
            "-"
        }
    }
}

#[component]
pub fn ListTest2(a: u32) -> Element {
    rsx! {
        if a % 3 == 0 {
            ListTest {
                test: 4u32,
                b:4u32,
                c:6u32
            }
        } else if a % 3 == 1 {
            ListTest {
                test: 5u32,
                b:6u32,
                c:6u32
            }
        } else {
            ListTest {
                test: 3u32,
                b:3u32,
                c:6u32
            }
        }
    }
}

#[component]
pub fn ListTest(test: ReadOnlySignal<u32>, b: u32, c: u32) -> Element {
    use_hook(|| log::info!("{test}, {b}, {c}"));
    rsx! {
        {test().to_string()}
        {b.to_string()}
        {c.to_string()}
    }
}

Expected behavior

The way i had it explained to me is that it shouldnt recreate the component at all with the above code

Environment:

  • Dioxus version: 0.51
  • Rust version: 1.76.0
  • OS info: MacOS
  • App platform: Web

Questionnaire

  • I'm interested in fixing this myself but don't know where to start
  • I would like to fix and I have a solution
  • I don't have time to fix this right now, but maybe later
@jkelleyrtp
Copy link
Member

Right now we do swap templates completely depending on the unique ID of every macro call. I believe there's a comment in the codebase to that effect too, though in this particular instance tossing a few checks in wouldn't terribly large overhead so we could support this usecase.

You could, if you wanted, drive the props from the conditional and pass it into a single rsx! call which won't swap templates between renders.

@ealmloff
Copy link
Member

ealmloff commented Apr 17, 2024

We don't guarantee this behavior, but I think this should be handled by light_diff_template. That code doesn't seem to be working correctly

@ealmloff ealmloff added the core relating to the core implementation of the virtualdom label Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core relating to the core implementation of the virtualdom
Projects
None yet
Development

No branches or pull requests

3 participants