Compare commits

...

5 Commits

Author SHA1 Message Date
Greg Johnston
90f4090845 cargo fmt 2023-05-05 12:25:57 -04:00
Greg Johnston
6b2133f46f fix suspense hydration 2023-05-05 12:25:53 -04:00
Greg Johnston
0482aa30b9 stash some work on examples 2023-04-28 17:04:36 -04:00
Greg Johnston
b68e39f9c9 clone Suspense rather than rendering it repeatedly 2023-04-28 16:48:24 -04:00
Greg Johnston
3cb9c04c08 move DynChild back into fragment when unmounting it, rather than only unmounting nodes 2023-04-28 16:48:13 -04:00
6 changed files with 81 additions and 22 deletions

View File

@@ -12,6 +12,7 @@ leptos = { path = "../../leptos" }
console_log = "1"
log = "0.4"
console_error_panic_hook = "0.1.7"
gloo-timers = { version = "0.2.6", features = ["futures"] }
[dev-dependencies]
wasm-bindgen = "0.2"

View File

@@ -1,24 +1,46 @@
use leptos::*;
/// A simple counter component.
///
/// You can use doc comments like this to document your component.
fn update_counter_bg(mut value: i32, step: i32, sig: WriteSignal<i32>) {
sig.set(value);
value += step;
if value < 1000 {
leptos::set_timeout(
move || {
update_counter_bg(value, step, sig);
},
std::time::Duration::from_millis(10),
);
}
}
#[component]
pub fn SimpleCounter(
cx: Scope,
/// The starting value for the counter
initial_value: i32,
/// The change that should be applied each time the button is clicked.
step: i32
step: i32,
) -> impl IntoView {
let (value, set_value) = create_signal(cx, initial_value);
// update the value signal periodically
update_counter_bg(initial_value, step, set_value);
view! { cx,
<div>
<button on:click=move |_| set_value(0)>"Clear"</button>
<button on:click=move |_| set_value.update(|value| *value -= step)>"-1"</button>
<span>"Value: " {value} "!"</span>
<button on:click=move |_| set_value.update(|value| *value += step)>"+1"</button>
<div>
<button on:click=move |_| set_value(0)>"Clear"</button>
<button on:click=move |_| set_value.update(|value| *value -= step)>"-1"</button>
<span>"Value: " {value} "!"</span>
<button on:click=move |_| set_value.update(|value| *value += step)>"+1"</button>
</div>
<Show when={move || value() % 2 == 0} fallback=|_| ()>
<For each={|| vec![1, 2, 3]} key=|key| *key view={move |cx, k| {
view! {
cx,
<article>{k}</article>
}
}}/>
</Show>
</div>
}
}
}

View File

@@ -72,6 +72,7 @@ pub fn fetch_example(cx: Scope) -> impl IntoView {
// and by using the ErrorBoundary fallback to catch Err(_)
// so we'll just implement our happy path and let the framework handle the rest
let cats_view = move || {
leptos::log!("rendering cats_view");
cats.read(cx).map(|data| {
data.map(|data| {
data.iter()
@@ -94,13 +95,13 @@ pub fn fetch_example(cx: Scope) -> impl IntoView {
}
/>
</label>
<ErrorBoundary fallback>
//<ErrorBoundary fallback>
<Transition fallback=move || {
view! { cx, <div>"Loading (Suspense Fallback)..."</div> }
}>
{cats_view}
</Transition>
</ErrorBoundary>
//</ErrorBoundary>
</div>
}
}

View File

@@ -65,7 +65,7 @@ pub fn Stories(cx: Scope) -> impl IntoView {
}}
</span>
<span>"page " {page}</span>
<Transition
<Suspense
fallback=move || view! { cx, <p>"Loading..."</p> }
>
<span class="page-link"
@@ -78,13 +78,13 @@ pub fn Stories(cx: Scope) -> impl IntoView {
"more >"
</a>
</span>
</Transition>
</Suspense>
</div>
<main class="news-list">
<div>
<Transition
<Suspense
fallback=move || view! { cx, <p>"Loading..."</p> }
set_pending=set_pending.into()
//set_pending=set_pending.into()
>
{move || match stories.read(cx) {
None => None,
@@ -105,7 +105,7 @@ pub fn Stories(cx: Scope) -> impl IntoView {
}.into_any())
}
}}
</Transition>
</Suspense>
</div>
</main>
</div>

View File

@@ -82,8 +82,17 @@ where
move || {
cfg_if! {
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
let mut child: Option<crate::View> = None;
if context.ready() {
Fragment::lazy(Box::new(|| vec![orig_child(cx).into_view(cx)])).into_view(cx)
Fragment::lazy(Box::new(|| vec![{
if let Some(child) = &child {
child.clone()
} else {
let first_run_child = orig_child(cx).into_view(cx);
child = Some(first_run_child.clone());
first_run_child
}
}])).into_view(cx)
} else {
Fragment::lazy(Box::new(|| vec![fallback().into_view(cx)])).into_view(cx)
}

View File

@@ -17,11 +17,11 @@ cfg_if! {
#[derive(Clone, PartialEq, Eq)]
pub struct DynChildRepr {
#[cfg(all(target_arch = "wasm32", feature = "web"))]
document_fragment: web_sys::DocumentFragment,
pub(crate) document_fragment: web_sys::DocumentFragment,
#[cfg(debug_assertions)]
opening: Comment,
pub(crate) child: Rc<RefCell<Box<Option<View>>>>,
closing: Comment,
pub(crate) closing: Comment,
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
pub(crate) id: HydrationKey,
}
@@ -278,7 +278,33 @@ where
let start = child.get_opening_node();
let end = &closing;
unmount_child(&start, end);
match child {
View::CoreComponent(
crate::CoreComponent::DynChild(
child,
),
) => {
let start =
child.get_opening_node();
let end = child.closing.node;
prepare_to_move(
&child.document_fragment,
&start,
&end,
);
}
View::Component(child) => {
let start =
child.get_opening_node();
let end = child.closing.node;
prepare_to_move(
&child.document_fragment,
&start,
&end,
);
}
_ => unmount_child(&start, end),
}
}
// Mount the new child