Closed winteler closed 1 month ago
I also wanted to mention that I got a similar error (not sure if it's exactly the same or not) with the code below that is quite a bit simpler. The error occurs when navigating to <TestPage/>
and then back to <HomePage/>
before the resource has finished loading.
use leptos::either::Either;
use leptos::prelude::*;
use leptos_meta::{provide_meta_context, MetaTags, Stylesheet, Title};
use leptos_router::{components::{Route, Router, Routes}, StaticSegment};
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>
}
}
#[server]
pub async fn data() -> Result<String, ServerFnError> {
tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
Ok(String::from("hello world"))
}
#[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/reproduce-leptos-0-7-beta5.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/>
<Route path=StaticSegment("/test") view=TestPage/>
</Routes>
</main>
</Router>
}
}
/// Renders the home page of your application.
#[component]
fn HomePage() -> impl IntoView {
view! {
<h1>"This is just a homepage for redirection"</h1>
<a href="/test">"Test page"</a>
}
}
/// The error occurs when navigating from Test Page to Base page before the resource finishes loading.
#[component]
fn TestPage() -> impl IntoView {
let resource = Resource::new(
move || (),
move |_| {
data()
}
);
view! {
<h2>"Test page"</h2>
<div>"The runtime errors occurs when navigating to the home page before the resource finishes loading"</div>
<a href="/">"BasePage"</a>
<SuspenseUnpack resource=resource let:value>
<div>{value.clone()}</div>
</SuspenseUnpack>
}
}
#[component]
pub fn SuspenseUnpack<
T: Clone + Send + Sync + 'static,
V: IntoView + 'static,
F: Fn(&T) -> V + Clone + Send + Sync + 'static,
>(
resource: Resource<Result<T, ServerFnError>>,
children: F,
) -> impl IntoView {
let children = StoredValue::new(children);
view! {
<Suspense>
{
move || Suspend::new(async move {
match &resource.await {
Ok(value) => Either::Left(children.with_value(|children| children(value))),
Err(_e) => Either::Right(view! { <div>"Error"</div> }),
}
})
}
</Suspense>
}
}
Thanks again for your work :)
Hello,
I think I've found a bug with stored children. It occurs when the result of a resource and a params are used together. I made a small example below to reproduce (not exactly like my app but I imagine it's the same error).
Leptos Dependencies
I also tried with rev = "17821f863a543feb70ccc70e0426deb78b6419ef" to see if https://github.com/leptos-rs/leptos/commit/17821f863a543feb70ccc70e0426deb78b6419ef made a difference but the error still occurred.
To Reproduce
Additional context You might need to go from
<BasePage/>
to<TestPage/>
more than once to get the error. In this particular example, the error doesn't seem to be such a big deal as you can continue to navigate but in my app it leads to other errors (that disappear if I read from theparam_map
with_untracked
).In that case, a part of the issue is that when navigating to
<BasePage/>
, the resource is reloaded despite it no longer being rendered on the new page. Would there be a relatively simple way to prevent the resource from reloading? That would be nice to avoid unnecessary requests.Please let me know if you need any other information and thanks for your help!