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

Buggy Resource/Transition #1742

Closed
cometship opened this issue Sep 16, 2023 · 3 comments · Fixed by #1753
Closed

Buggy Resource/Transition #1742

cometship opened this issue Sep 16, 2023 · 3 comments · Fixed by #1753
Labels
bug Something isn't working

Comments

@cometship
Copy link

Describe the bug
When using create_server_action/create_server_multi_action, a derived value with .with() and a Transition the DOM-Element gets duplicated the first two times the Resource is updated.

Some crude minimal repro:

#[cfg(feature = "ssr")]
use std::sync::Mutex;
#[cfg(feature = "ssr")]
static DATA: Mutex<Vec<String>> = Mutex::new(Vec::new());

#[server]
async fn fetch_data() -> Result<Vec<String>, ServerFnError> {
    Ok(DATA.lock().unwrap().clone())
}

#[server]
async fn add_data(data: String) -> Result<(), ServerFnError> {
    DATA.lock().unwrap().push(data);
    Ok(())
}

#[component]
fn HomePage() -> impl IntoView {
    let add_data = create_server_action::<AddData>();
    let data = create_resource(add_data.version(), |_| fetch_data());

    let data_len = move || {
        data.with(|data| {
            if let Some(Ok(data)) = data {
                data.iter().count()
            } else {
                0
            }
        })
    };

    view! {
        <Transition fallback=move || view! { <p>Loading...</p> }>
            <div>{data_len}</div>
        </Transition>
        <ActionForm action=add_data>
            <input type="text" name="data" />
            <button type="submit">Add</button>
        </ActionForm>
    }
}

Leptos Dependencies

leptos = { version = "0.5.0-rc2", features = ["nightly"] }
leptos_axum = { version = "0.5.0-rc2", optional = true }
leptos_meta = { version = "0.5.0-rc2", features = ["nightly"] }
leptos_router = { version = "0.5.0-rc2", features = ["nightly"] }

To Reproduce
Steps to reproduce the behavior:

  1. Start the example above. Rest of the code is same like the starter (adapted to v0.5.0-rc2).
  2. Notice that it shows 0 above the input.
  3. Write something in the input box and press Add.
  4. It now shows 1 and below another 1.
  5. Press Add again.
  6. It now shows 1 and below 2.
  7. Press Add again.
  8. It now shows 3.
  9. Now every Add press works as expected.

Expected behavior
It should show just one count and that count should update with every Add press.

Screenshots
image
image
image
image

@cometship
Copy link
Author

cometship commented Sep 17, 2023

Another (buggy) example where I wanted to implement a fade-in for newly added elements:

app.rs

#[cfg(feature = "ssr")]
use std::sync::Mutex;
#[cfg(feature = "ssr")]
static DATA: Mutex<Vec<String>> = Mutex::new(Vec::new());

#[server]
async fn fetch_data() -> Result<Vec<String>, ServerFnError> {
    std::thread::sleep(std::time::Duration::from_millis(1250));

    Ok(DATA.lock().unwrap().clone())
}

#[server]
async fn add_data(data: String) -> Result<(), ServerFnError> {
    std::thread::sleep(std::time::Duration::from_millis(1250));

    DATA.lock().unwrap().push(data);
    Ok(())
}

#[component]
fn HomePage() -> impl IntoView {
    let add_data = create_server_action::<AddData>();
    let data = create_resource(add_data.version(), |_| fetch_data());

    let data_len = move || {
        data.with(|data| {
            if let Some(Ok(data)) = data {
                data.iter().count()
            } else {
                0
            }
        })
    };

    view! {
        <Transition fallback=move || view! { <p>Loading...</p> }>
            <div>{data_len}</div>
            <ul>
                <For
                    each=move || data.get().map(|d| d.unwrap()).unwrap_or_else(|| vec![])
                    key=|d| d.clone()
                    view=move |d| view! { <div class="fade">{d}</div> }
                />
            </ul>
            </Transition>
        <ActionForm action=add_data>
            <input type="text" name="data" />
            <button type="submit">Add</button>
        </ActionForm>
    }
}

main.scss

@keyframes fade {
	0% {
		transform: translateY(40px);
		opacity: 0;
	}

	100% {
		transform: translateY(0);
		opacity: 1;
	}
}


.fade {
	animation: fade 0.6s ease;
}

But it seems to fade in all elements and not only the new one. Also it shows the first added data for every following add.

bug.webm

@gbj gbj added the bug Something isn't working label Sep 18, 2023
@gbj gbj closed this as completed in 2b59ae1 Sep 18, 2023
@gbj
Copy link
Collaborator

gbj commented Sep 19, 2023

@cometship The second example is caused by an unrelated issue, and has turned up a bug in which Suspense sometimes renders its children twice — so, thanks for that! I will handle it separately.

gbj added a commit that referenced this issue Sep 19, 2023
@gbj gbj mentioned this issue Sep 19, 2023
@cometship
Copy link
Author

Was not sure if it is related or not 😅
Thanks for fixing it! 😊
Will check the PR now.

gbj added a commit that referenced this issue Sep 19, 2023
gbj added a commit that referenced this issue Sep 20, 2023
…=> extra animations)"

This reverts commit fafb6c0.
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

Successfully merging a pull request may close this issue.

2 participants