leptos-rs / leptos

Build fast web applications with Rust.
https://leptos.dev
MIT License
16.24k stars 644 forks source link

`Transition` doesn't show fallback while pending #562

Closed kiyov09 closed 1 year ago

kiyov09 commented 1 year ago

I noticed that the Transition component is not rendering the fallback while the resource inside is still pending.

Example Code

pub async fn test_resources() -> Vec<String> {
    std::thread::sleep(std::time::Duration::from_secs(2));
    vec![
        "Fizz".to_string(),
        "Buzz".to_string(),
        "FizzBuzz".to_string(),
    ]
}

#[component]
pub fn ResourcesIssue(cx: Scope) -> impl IntoView {
    let resource = create_resource(cx, move || (), move |_| test_resources());

    view! {
        cx,
        <div>
            <Transition fallback=move || view!{ cx, <p>"Loading..."</p>}>
            {
                move || resource.read(cx).map(|strs|
                    strs.iter()
                        .map(|s| view!{ cx, <p>{s}</p>})
                        .collect::<Vec<_>>(),
                )
            }
            </Transition>
        </div>
    }
}

I was analyzing the code and seems to be related to this if-else block: https://github.com/leptos-rs/leptos/blob/4ff08f042b643d542546076edc748a0b4582cb55/leptos/src/transition.rs#L87-L91

gbj commented 1 year ago

Ah, thanks very much for reporting this!

kiyov09 commented 1 year ago

@gbj First of all thnx for your work on this. 💪

It's working now but only when combined with create_resource. If I used create_local_resource (which I'm doing in my project) the issue is still there.

kiyov09 commented 1 year ago

Probably the new first_run Cell needs to be read/modified inside the fallback instead of the children At least that works for me.

I can continue with this if you want.

gbj commented 1 year ago

Probably the new first_run Cell needs to be read/modified inside the fallback instead of the children

At least that works for me.

I can continue with this if you want.

Ah okay! Want to make a PR?

kiyov09 commented 1 year ago

Sure. I'll work on that tomorrow morning. Is that ok?

kiyov09 commented 1 year ago

@gbj Ok, I found what's the issue, but I don't know the proper way to fix it. When on hydrate mode, the first run happens on the server, which sends the initial HTML with the fallback on it ("Loading..." in this case). When it gets to the client, the prev_children gets updated right away in the first run but it is an "invisible" element cause the resource is still pending (See screenshot below), so the fallback element sent by the server is removed.

Screenshot 2023-02-23 at 10 13 10
gbj commented 1 year ago

Ah okay I'll take a look.