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

[0.7] <Transition> partially duplicates inserted vec! #3465

Open
okami-fellow opened this issue Jan 9, 2025 · 1 comment
Open

[0.7] <Transition> partially duplicates inserted vec! #3465

okami-fellow opened this issue Jan 9, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@okami-fellow
Copy link

Describe the bug
When I have two <Transition> with respectful Resource::new() side by side in one view! it results in partial duplication of the second <Transition> content .

Leptos Dependencies

leptos = { version = "0.7.3" }
leptos_router = { version = "0.7.3" }
axum = { version = "0.7", optional = true }
console_error_panic_hook = "0.1"
leptos_axum = { version = "0.7.3", optional = true }
leptos_meta = { version = "0.7.3" }
tokio = { version = "1", features = ["rt-multi-thread"], optional = true }
tower = { version = "0.4", optional = true }
tower-http = { version = "0.5", features = ["fs"], optional = true }
wasm-bindgen = "=0.2.99"
thiserror = "1"
http = "1"

To Reproduce
Update app.rs in fresh start-axum template:

use leptos::prelude::*;
use leptos_meta::{provide_meta_context, MetaTags, Stylesheet, Title};
use leptos_router::{
    components::{Route, Router, Routes},
    StaticSegment,
};
use leptos::either::EitherOf3;

pub fn shell(options: LeptosOptions) -> impl IntoView {
    view! {
        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="utf-8"/>
                <meta name="viewport" content="width=device-width, initial-scale=1"/>
                <AutoReload options=options.clone() />
                <HydrationScripts options/>
                <MetaTags/>
            </head>
            <body>
                <App/>
            </body>
        </html>
    }
}

#[component]
pub fn App() -> impl IntoView {
    // Provides context that manages stylesheets, titles, meta tags, etc.
    provide_meta_context();

    view! {
        // injects a stylesheet into the document <head>
        // id=leptos means cargo-leptos will hot-reload this stylesheet
        <Stylesheet id="leptos" href="/pkg/test.css"/>

        // sets the document title
        <Title text="Welcome to Leptos"/>

        // content for this welcome page
        <Router>
            <main>
                <Routes fallback=|| "Page not found.".into_view()>
                    <Route path=StaticSegment("") view=HomePage/>
                </Routes>
            </main>
        </Router>
    }
}

/// Renders the home page of your application.
#[component]
fn HomePage() -> impl IntoView {

    let first_list_update = RwSignal::new(false);
    let first_list_resource = Resource::new(
        move || first_list_update.get(),
        |_| first_fn()
    );
    let first_list = move ||
        first_list_resource.get().map(|value|
            match value {
                Ok(data) => EitherOf3::A(
                    view! {
                        {data.into_iter().map(|str| {

                            view! {
                                <span>{str}</span>
                            }
                        }).collect_view()}
                    }.into_view()
                ),
                Err(_) => EitherOf3::B(view! {<div>"List Is Empty"</div>}.into_view()),
            }
        ).unwrap_or_else(|| EitherOf3::C(view! {<div>"Item Is Missing"</div>}.into_view())
    );

    let second_list_update = RwSignal::new(false);
    let second_list_resource = Resource::new(
        move || second_list_update.get(),
        |_| second_fn()
    );
    let second_list = move ||
        second_list_resource.get().map(|value|
            match value {
                Ok(data) => EitherOf3::A(
                    view! {
                        {data.into_iter().map(|str| {

                            view! {
                                <span>{str}</span>
                            }
                        }).collect_view()}
                    }.into_view()
                ),
                Err(_) => EitherOf3::B(view! {<div>"List Is Empty"</div>}.into_view()),
            }
        ).unwrap_or_else(|| EitherOf3::C(view! {<div>"Item Is Missing"</div>}.into_view())
    );

    view! {
        <Transition fallback=|| view! {<div>"Loading"</div>}>{first_list}</Transition>
        <br/><br/>
        <Transition fallback=|| view! {<div>"Loading"</div>}>{second_list}</Transition>
    }
}

#[server]
pub async fn first_fn() -> Result<Vec<String>, ServerFnError> {
    Ok(vec![String::from("one, "), String::from("two, "), String::from("three, "), String::from("four")])
}

#[server]
pub async fn second_fn() -> Result<Vec<String>, ServerFnError> {
    Ok(vec![String::from("1, "), String::from("2, "), String::from("3, "), String::from("4, ")])
}

Expected behavior
Transition with second_list should be displaying this: 1, 2, 3, 4,
But you will get this: 1, 2, 3, 4, 2, 3, 4,

Additional context

  • It "kind" of work okay if:
    -- Remove fallback in <Transition>
    -- Insert <Transition> into another <Transition>
    -- Change Resource to OnceResource

  • rustup 1.27.1 (54dd3d00f 2024-04-24);

  • Installed toolchains: stable-x86_64-pc-windows-msvc;

  • Installed targets for active toolchain: wasm32-unknown-unknown;

  • Active toolchain: rustc 1.83.0 (90b35a623 2024-11-26);

  • cargo-leptos 0.2.24;

@gbj gbj added the bug Something isn't working label Jan 10, 2025
@gbj
Copy link
Collaborator

gbj commented Jan 10, 2025

Ah! I seem to have fixed the same issue for Suspense (or at least prevented it from occurring) in fa731d5 some time ago, but not made the same change for Transition. #3471 should fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants