mirror of https://github.com/yewstack/yew
Update documentation around Children (#3297)
* Update Children to use Html. * Fix website. * Update website/docs/advanced-topics/children.mdx * add further reading section --------- Co-authored-by: Muhammad Hamza <muhammadhamza1311@gmail.com>
This commit is contained in:
parent
4daa2ecc8a
commit
d803df9336
|
@ -2,6 +2,18 @@
|
|||
title: 'Children'
|
||||
---
|
||||
|
||||
:::caution
|
||||
|
||||
Inspecting and manipulating `Children` can often result in surprising and hard-to-explain behaviours in your application.
|
||||
This can lead to edge cases and often does not yield expected result.
|
||||
You should consider other approaches if you are trying to manipulate `Children`.
|
||||
|
||||
Yew supports using `Html` as the type of the children prop.
|
||||
You should use `Html` as children if you do not need `Children` or `ChildrenRenderer`.
|
||||
It doesn't have the drawbacks of `Children` and has a lower performance overhead.
|
||||
|
||||
:::
|
||||
|
||||
## General usage
|
||||
|
||||
_Most of the time,_ when allowing a component to have children, you don't care
|
||||
|
@ -9,12 +21,12 @@ what type of children the component has. In such cases, the below example will
|
|||
suffice.
|
||||
|
||||
```rust
|
||||
use yew::{html, Children, Component, Context, Html, Properties};
|
||||
use yew::{html, Component, Context, Html, Properties};
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct ListProps {
|
||||
#[prop_or_default]
|
||||
pub children: Children,
|
||||
pub children: Html,
|
||||
}
|
||||
|
||||
pub struct List;
|
||||
|
@ -30,7 +42,7 @@ impl Component for List {
|
|||
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||
html! {
|
||||
<div class="list">
|
||||
{ for ctx.props().children.iter() }
|
||||
{ctx.props().children.clone()}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +102,53 @@ impl Component for List {
|
|||
}
|
||||
```
|
||||
|
||||
## Nested Children with Props
|
||||
|
||||
Nested component properties can be accessed and mutated if the containing component types its children.
|
||||
|
||||
```rust
|
||||
use std::rc::Rc;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct ListItemProps {
|
||||
value: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
fn ListItem(props: &ListItemProps) -> Html {
|
||||
let ListItemProps { value } = props.clone();
|
||||
html! {
|
||||
<span>
|
||||
{value}
|
||||
</span>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub children: ChildrenWithProps<ListItem>,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
fn List(props: &Props) -> Html {
|
||||
let modified_children = props.children.iter().map(|mut item| {
|
||||
let mut props = Rc::make_mut(&mut item.props);
|
||||
props.value = format!("item-{}", props.value);
|
||||
item
|
||||
});
|
||||
html! { for modified_children }
|
||||
}
|
||||
|
||||
html! {
|
||||
<List>
|
||||
<ListItem value="a" />
|
||||
<ListItem value="b" />
|
||||
<ListItem value="c" />
|
||||
</List>
|
||||
};
|
||||
```
|
||||
|
||||
### Enum typed children
|
||||
|
||||
Of course, sometimes you might need to restrict the children to a few different
|
||||
|
@ -253,3 +312,7 @@ pub fn render_page(with_sidebar: bool) -> Html {
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
||||
- For a real-world example of this pattern, check out the yew-router source code. For a more advanced example, check out the [nested-list example](https://github.com/yewstack/yew/tree/master/examples/nested_list) in the main yew repository.
|
||||
|
|
|
@ -28,7 +28,7 @@ use yew::prelude::*;
|
|||
#[derive(Properties, PartialEq)]
|
||||
pub struct ModalProps {
|
||||
#[prop_or_default]
|
||||
pub children: Children,
|
||||
pub children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
|
@ -38,7 +38,7 @@ fn Modal(props: &ModalProps) -> Html {
|
|||
.expect("Expected to find a #modal_host element");
|
||||
|
||||
create_portal(
|
||||
html!{ {for props.children.iter()} },
|
||||
props.children.clone(),
|
||||
modal_host.into(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ This situation is called "Prop Drilling".
|
|||
Consider the following example which passes down the theme using props:
|
||||
|
||||
```rust
|
||||
use yew::{html, Children, Component, Context, Html, Properties, function_component};
|
||||
use yew::{html, Component, Context, Html, Properties, function_component};
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct Theme {
|
||||
|
@ -51,7 +51,7 @@ fn Navbar(props: &NavbarProps) -> Html {
|
|||
#[derive(PartialEq, Properties)]
|
||||
pub struct ThemeProps {
|
||||
theme: Theme,
|
||||
children: Children,
|
||||
children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
|
|
|
@ -5,7 +5,7 @@ title: 'Children'
|
|||
`Children` is a special prop type that allows you to receive nested `Html` that is provided like html child elements.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties, Children};
|
||||
use yew::{function_component, html, Html, Properties};
|
||||
|
||||
#[function_component]
|
||||
fn App() -> Html {
|
||||
|
@ -22,7 +22,7 @@ fn App() -> Html {
|
|||
#[derive(Properties, PartialEq)]
|
||||
pub struct Props {
|
||||
// highlight-next-line
|
||||
pub children: Children, // the field name `children` is important!
|
||||
pub children: Html, // the field name `children` is important!
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
|
@ -30,12 +30,8 @@ fn HelloWorld(props: &Props) -> Html {
|
|||
html! {
|
||||
<div class="very-stylized-container">
|
||||
// highlight-next-line
|
||||
{ for props.children.iter() } // you can forward children like this
|
||||
{ props.children.clone() } // you can forward children like this
|
||||
</div>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Further reading
|
||||
|
||||
- [Advanced ways to handle children](../../advanced-topics/children)
|
||||
|
|
|
@ -104,7 +104,7 @@ struct Props {
|
|||
#[prop_or_default]
|
||||
class: Classes,
|
||||
fill: bool,
|
||||
children: Children,
|
||||
children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
|
|
|
@ -63,7 +63,7 @@ use yew::prelude::*;
|
|||
#[derive(PartialEq, Properties)]
|
||||
struct Props {
|
||||
id: String,
|
||||
children: Children,
|
||||
children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
|
@ -94,7 +94,7 @@ use yew::prelude::*;
|
|||
#[derive(PartialEq, Properties)]
|
||||
struct Props {
|
||||
id: String,
|
||||
children: Children,
|
||||
children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
|
@ -108,7 +108,7 @@ fn Container(props: &Props) -> Html {
|
|||
|
||||
let props = yew::props!(Props {
|
||||
id: "container-2",
|
||||
children: Children::default(),
|
||||
children: Html::default(),
|
||||
});
|
||||
|
||||
html! {
|
||||
|
@ -119,53 +119,6 @@ html! {
|
|||
};
|
||||
```
|
||||
|
||||
## Nested Children with Props
|
||||
|
||||
Nested component properties can be accessed and mutated if the containing component types its children. In the following example, the `List` component can wrap `ListItem` components. For a real-world example of this pattern, check out the `yew-router` source code. For a more advanced example, check out the `nested-list` example in the main yew repository.
|
||||
|
||||
```rust
|
||||
use std::rc::Rc;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct ListItemProps {
|
||||
value: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
fn ListItem(props: &ListItemProps) -> Html {
|
||||
let ListItemProps { value } = props.clone();
|
||||
html! {
|
||||
<span>
|
||||
{value}
|
||||
</span>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub children: ChildrenWithProps<ListItem>,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
fn List(props: &Props) -> Html {
|
||||
let modified_children = props.children.iter().map(|mut item| {
|
||||
let mut props = Rc::make_mut(&mut item.props);
|
||||
props.value = format!("item-{}", props.value);
|
||||
item
|
||||
});
|
||||
html! { for modified_children }
|
||||
}
|
||||
|
||||
html! {
|
||||
<List>
|
||||
<ListItem value="a" />
|
||||
<ListItem value="b" />
|
||||
<ListItem value="c" />
|
||||
</List>
|
||||
};
|
||||
```
|
||||
|
||||
## Relevant examples
|
||||
|
||||
- [Function Todo MVC](https://github.com/yewstack/yew/tree/master/examples/function_todomvc)
|
||||
|
|
Loading…
Reference in New Issue