fix(host-detail): switch host resource to LocalResource to fix hydration mismatch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 10:12:30 +02:00
parent 54a5c2525f
commit f5058bd54a

View File

@@ -255,18 +255,17 @@ pub fn HostDetailPage() -> impl IntoView {
} }
}); });
// Reload host detail after any mutation. // LocalResource avoids reading the resource outside <Suspense> during hydration,
let host = Resource::new( // which would cause a mismatch between the SSR-rendered fallback and the content
move || ( // the WASM expects to find after the resource resolves.
host_id(), let host = LocalResource::new(move || {
update_action.version().get(), let _ = update_action.version().get();
add_port_action.version().get(), let _ = add_port_action.version().get();
remove_port_action.version().get(), let _ = remove_port_action.version().get();
add_app_action.version().get(), let _ = add_app_action.version().get();
remove_app_action.version().get(), let _ = remove_app_action.version().get();
), get_host_detail(host_id())
|(id, _, _, _, _, _)| get_host_detail(id), });
);
// Networks dropdown — LocalResource avoids SSR/hydration mismatch. // Networks dropdown — LocalResource avoids SSR/hydration mismatch.
let networks_res = LocalResource::new(|| get_networks()); let networks_res = LocalResource::new(|| get_networks());
@@ -286,12 +285,15 @@ pub fn HostDetailPage() -> impl IntoView {
let new_port = RwSignal::new(String::new()); let new_port = RwSignal::new(String::new());
// Sync edit signals whenever fresh host data arrives. // Sync edit signals whenever fresh host data arrives.
// LocalResource wraps its value in SendWrapper, so we dereference with `*r`.
Effect::new(move |_| { Effect::new(move |_| {
if let Some(Ok(ref detail)) = host.get() { if let Some(r) = host.get() {
if let Ok(ref detail) = *r {
name_sig.set(detail.name.clone()); name_sig.set(detail.name.clone());
ip_sig.set(detail.ip.clone()); ip_sig.set(detail.ip.clone());
net_id_sig.set(detail.network_id); net_id_sig.set(detail.network_id);
} }
}
}); });
let navigate = use_navigate(); let navigate = use_navigate();
@@ -304,7 +306,7 @@ pub fn HostDetailPage() -> impl IntoView {
view! { view! {
<div class="host-detail-page"> <div class="host-detail-page">
<Suspense fallback=|| view! { <p class="empty">"Loading host…"</p> }> <Suspense fallback=|| view! { <p class="empty">"Loading host…"</p> }>
{move || host.get().map(|result| match result { {move || host.get().map(|r| match (*r).clone() {
Err(e) => view! { Err(e) => view! {
<p class="error">"Could not load host: " {e.to_string()}</p> <p class="error">"Could not load host: " {e.to_string()}</p>
}.into_any(), }.into_any(),