mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
Merge pull request #2799 from leptos-rs/2798
fix: ProtectedRoute calling view multiple times during server rendering
This commit is contained in:
commit
693861434c
2 changed files with 103 additions and 2 deletions
|
@ -442,3 +442,101 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A wrapper that prevents [`Suspense`] from waiting for any resource reads that happen inside
|
||||||
|
/// `Unsuspend`.
|
||||||
|
pub struct Unsuspend<T>(Box<dyn FnOnce() -> T + Send>);
|
||||||
|
|
||||||
|
impl<T> Unsuspend<T> {
|
||||||
|
/// Wraps the given function, such that it is not called until all resources are ready.
|
||||||
|
pub fn new(fun: impl FnOnce() -> T + Send + 'static) -> Self {
|
||||||
|
Self(Box::new(fun))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, Rndr> Render<Rndr> for Unsuspend<T>
|
||||||
|
where
|
||||||
|
T: Render<Rndr>,
|
||||||
|
Rndr: Renderer,
|
||||||
|
{
|
||||||
|
type State = T::State;
|
||||||
|
|
||||||
|
fn build(self) -> Self::State {
|
||||||
|
(self.0)().build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rebuild(self, state: &mut Self::State) {
|
||||||
|
(self.0)().rebuild(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, Rndr> AddAnyAttr<Rndr> for Unsuspend<T>
|
||||||
|
where
|
||||||
|
T: AddAnyAttr<Rndr> + 'static,
|
||||||
|
Rndr: Renderer,
|
||||||
|
{
|
||||||
|
type Output<SomeNewAttr: Attribute<Rndr>> =
|
||||||
|
Unsuspend<T::Output<SomeNewAttr::CloneableOwned>>;
|
||||||
|
|
||||||
|
fn add_any_attr<NewAttr: Attribute<Rndr>>(
|
||||||
|
self,
|
||||||
|
attr: NewAttr,
|
||||||
|
) -> Self::Output<NewAttr>
|
||||||
|
where
|
||||||
|
Self::Output<NewAttr>: RenderHtml<Rndr>,
|
||||||
|
{
|
||||||
|
let attr = attr.into_cloneable_owned();
|
||||||
|
Unsuspend::new(move || (self.0)().add_any_attr(attr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, Rndr> RenderHtml<Rndr> for Unsuspend<T>
|
||||||
|
where
|
||||||
|
T: RenderHtml<Rndr> + 'static,
|
||||||
|
Rndr: Renderer,
|
||||||
|
{
|
||||||
|
type AsyncOutput = Self;
|
||||||
|
|
||||||
|
const MIN_LENGTH: usize = T::MIN_LENGTH;
|
||||||
|
|
||||||
|
fn dry_resolve(&mut self) {}
|
||||||
|
|
||||||
|
async fn resolve(self) -> Self::AsyncOutput {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_html_with_buf(
|
||||||
|
self,
|
||||||
|
buf: &mut String,
|
||||||
|
position: &mut Position,
|
||||||
|
escape: bool,
|
||||||
|
mark_branches: bool,
|
||||||
|
) {
|
||||||
|
(self.0)().to_html_with_buf(buf, position, escape, mark_branches);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_html_async_with_buf<const OUT_OF_ORDER: bool>(
|
||||||
|
self,
|
||||||
|
buf: &mut StreamBuilder,
|
||||||
|
position: &mut Position,
|
||||||
|
escape: bool,
|
||||||
|
mark_branches: bool,
|
||||||
|
) where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
(self.0)().to_html_async_with_buf::<OUT_OF_ORDER>(
|
||||||
|
buf,
|
||||||
|
position,
|
||||||
|
escape,
|
||||||
|
mark_branches,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hydrate<const FROM_SERVER: bool>(
|
||||||
|
self,
|
||||||
|
cursor: &Cursor<Rndr>,
|
||||||
|
position: &PositionState,
|
||||||
|
) -> Self::State {
|
||||||
|
(self.0)().hydrate::<FROM_SERVER>(cursor, position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -331,12 +331,15 @@ where
|
||||||
(view! {
|
(view! {
|
||||||
<Transition>
|
<Transition>
|
||||||
{move || {
|
{move || {
|
||||||
match condition() {
|
let condition = condition();
|
||||||
|
let view = view.clone();
|
||||||
|
let redirect_path = redirect_path.clone();
|
||||||
|
Unsuspend::new(move || match condition {
|
||||||
Some(true) => Either::Left(view()),
|
Some(true) => Either::Left(view()),
|
||||||
#[allow(clippy::unit_arg)]
|
#[allow(clippy::unit_arg)]
|
||||||
Some(false) => Either::Right(view! { <Redirect path=redirect_path()/> }),
|
Some(false) => Either::Right(view! { <Redirect path=redirect_path()/> }),
|
||||||
None => Either::Right(()),
|
None => Either::Right(()),
|
||||||
}
|
})
|
||||||
}}
|
}}
|
||||||
|
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
Loading…
Reference in a new issue