--- title: "Components" description: "Create complex layouts with component hierarchies" --- ## Basic Any type that implements `Component` can be used in the `html!` macro: ```rust use yew::{Component, Html, html, Context, Properties}; struct MyComponent; impl Component for MyComponent { type Message = (); type Properties = (); fn create(_ctx: &Context) -> Self { Self } fn view(&self, _ctx: &Context) -> Html { html! { { "This component has no properties!" } } } } #[derive(Clone, PartialEq, Properties)] struct Props { prop1: String, prop2: String, } struct MyComponentWithProps; impl Component for MyComponentWithProps { type Message = (); type Properties = Props; fn create(_ctx: &Context) -> Self { Self } fn view(&self, ctx: &Context) -> Html { html! { { format!( "prop1: {} and prop2: {}", ctx.props().prop1, ctx.props().prop2 ) } } } } let props = Props { prop1: "Hello".to_owned(), prop2: "World".to_owned(), }; html!{ <> // No properties // With Properties // With the whole set of props provided at once // With Properties from a variable and specific values overridden }; ``` ## Nested Components can be passed children if they have a `children` field in their `Properties`. ```rust title="parent.rs" use yew::{Children, Component, Context, html, Html, Properties}; #[derive(PartialEq, Properties)] struct Props { id: String, children: Children, } struct Container; impl Component for Container { type Message = (); type Properties = Props; fn create(_ctx: &Context) -> Self { Self } fn view(&self, ctx: &Context) -> Html { html! {
{ ctx.props().children.clone() }
} } } html! {

{ "Hi" }

{ "Hello" }
}; ``` The `html!` macro allows you to pass a base expression with the `..props` syntax instead of specifying each property individually, similar to Rust's [Functional Update Syntax](https://doc.rust-lang.org/stable/reference/expressions/struct-expr.html#functional-update-syntax). This base expression must occur after any individual props are passed. When passing a base props expression with a `children` field, the children passed in the `html!` macro overwrite the ones already present in the props. ```rust use yew::{Children, Component, Context, html, Html, props, Properties}; #[derive(PartialEq, Properties)] struct Props { id: String, children: Children, } struct Container; impl Component for Container { type Message = (); type Properties = Props; fn create(_ctx: &Context) -> Self { Self } fn view(&self, ctx: &Context) -> Html { html! {
{ ctx.props().children.clone() }
} } } let props = yew::props!(Container::Properties { id: "container-2", children: Children::default(), }); html! { // props.children will be overwritten with this { "I am a child, as you can see" } }; ``` ## 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::{html, ChildrenWithProps, Component, Context, Html, Properties}; #[derive(Clone, PartialEq, Properties)] pub struct ListItemProps { value: String, } pub struct ListItem; impl Component for ListItem { type Message = (); type Properties = ListItemProps; fn create(_ctx: &Context) -> Self { Self } fn view(&self, ctx: &Context) -> Html { html! { { ctx.props().value.clone() } } } } #[derive(PartialEq, Properties)] pub struct Props { pub children: ChildrenWithProps, } pub struct List; impl Component for List { type Message = (); type Properties = Props; fn create(_ctx: &Context) -> Self { Self } fn view(&self, ctx: &Context) -> Html { html! {{ for ctx.props().children.iter().map(|mut item| { let mut props = Rc::make_mut(&mut item.props); props.value = format!("item-{}", props.value); item }) }} } } html! { }; ``` ## Relevant examples - [Boids](https://github.com/yewstack/yew/tree/master/examples/boids) - [Router](https://github.com/yewstack/yew/tree/master/examples/router) - [Store](https://github.com/yewstack/yew/tree/master/examples/store)