This is unreleased documentation for Yew Next version.
For up-to-date documentation, see the latest version on docs.rs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! Primitive Components & Properties Types

use crate::function_component;
use crate::html::{BaseComponent, ChildrenProps, Html};

/// A Component to represent a component that does not exist in current implementation.
///
/// During Hydration, Yew expected the Virtual DOM hierarchy to match the the layout used in
/// server-side rendering. However, sometimes it is possible / reasonable to omit certain components
/// from one side of the implementation. This component is used to represent a component as if a
/// component "existed" in the place it is defined.
///
/// # Warning
///
/// The Real DOM hierarchy must also match the server-side rendered artifact. This component is
/// only usable when the original component does not introduce any additional elements. (e.g.:
/// Context Providers)
///
/// A generic parameter is provided to help identify the component to be substituted.
/// The type of the generic parameter is not required to be the same component that was in the other
/// implementation. However, this behaviour may change in the future if more debug assertions were
/// to be introduced. It is recommended that the generic parameter represents the component in the
/// other implementation.
///
/// # Example
///
/// ```
/// use yew::prelude::*;
/// # use yew::html::ChildrenProps;
/// #
/// # #[function_component]
/// # fn Comp(props: &ChildrenProps) -> Html {
/// #     Html::default()
/// # }
/// #
/// # #[function_component]
/// # fn Provider(props: &ChildrenProps) -> Html {
/// #     let children = props.children.clone();
/// #
/// #     html! { <>{children}</> }
/// # }
/// # type Provider1 = Provider;
/// # type Provider2 = Provider;
/// # type Provider3 = Provider;
/// # type Provider4 = Provider;
///
/// #[function_component]
/// fn ServerApp() -> Html {
///     // The Server Side Rendering Application has 3 Providers.
///     html! {
///         <Provider1>
///             <Provider2>
///                 <Provider3>
///                     <Comp />
///                 </Provider3>
///             </Provider2>
///         </Provider1>
///     }
/// }
///
/// #[function_component]
/// fn App() -> Html {
///     // The Client Side Rendering Application has 4 Providers.
///     html! {
///         <Provider1>
///             <Provider2>
///                 <Provider3>
///
///                     // This provider does not exist on the server-side
///                     // Hydration will fail due to Virtual DOM layout mismatch.
///                     <Provider4>
///                         <Comp />
///                     </Provider4>
///
///                 </Provider3>
///             </Provider2>
///         </Provider1>
///     }
/// }
/// ```
///
/// To mitigate this, we can use a `PhantomComponent`:
///
/// ```
/// use yew::prelude::*;
/// # use yew::html::{PhantomComponent, ChildrenProps};
/// #
/// # #[function_component]
/// # fn Comp(props: &ChildrenProps) -> Html {
/// #     Html::default()
/// # }
/// #
/// # #[function_component]
/// # fn Provider(props: &ChildrenProps) -> Html {
/// #     let children = props.children.clone();
/// #
/// #     html! { <>{children}</> }
/// # }
/// # type Provider1 = Provider;
/// # type Provider2 = Provider;
/// # type Provider3 = Provider;
/// # type Provider4 = Provider;
///
/// #[function_component]
/// fn ServerApp() -> Html {
///     html! {
///         <Provider1>
///             <Provider2>
///                 <Provider3>
///                     // We add a PhantomComponent for Provider4,
///                     // it acts if a Provider4 component presents in this position.
///                     <PhantomComponent<Provider4>>
///                         <Comp />
///                     </PhantomComponent<Provider4>>
///                 </Provider3>
///             </Provider2>
///         </Provider1>
///     }
/// }
///
/// #[function_component]
/// fn App() -> Html {
///     html! {
///         <Provider1>
///             <Provider2>
///                 <Provider3>
///
///                     // Hydration will succeed as the PhantomComponent in the server-side
///                     // implementation will represent a Provider4 component in this position.
///                     <Provider4>
///                         <Comp />
///                     </Provider4>
///
///                 </Provider3>
///             </Provider2>
///         </Provider1>
///     }
/// }
/// ```
#[function_component]
pub fn PhantomComponent<T>(props: &ChildrenProps) -> Html
where
    T: BaseComponent,
{
    props.children.clone()
}