---
title: 'Properties'
description: 'Parent to child communication'
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'

:::note

Properties are often shortened as "Props".

:::

Properties are essentially component arguments that Yew can keep watch on.

A type has to implement the `Properties` trait before it can be used as the properties of a component.

## Reactivity

Yew checks if props have changed when reconciling the vdom during rerendering, to know if nested components needs to be rerendered.
This way Yew can be considered a very reactive framework as changes from the parent will always be propagated downwards
and the view will never be out of sync from the data coming from props/state.

:::tip

If you have not yet completed the [tutorial](../../tutorial), try it out and test this reactivity yourself!

:::

## Derive macro

Yew provides a derive macro to easily implement the `Properties` trait on structs.

Types for which you derive `Properties` must also implement `PartialEq` so Yew can do data comparison.

```rust
use yew::Properties;

#[derive(Properties, PartialEq)]
pub struct Props {
    pub is_loading: bool,
}
```

## Use in function components

The attribute `#[function_component]` allows to optionally receive Props in the function arguments. To supply them,
they are assigned via attributes in the `html!` macro.

<Tabs>
  <TabItem value="with-props" label="With Props">

```rust
use yew::{function_component, html, Html, Properties};

#[derive(Properties, PartialEq)]
pub struct Props {
    pub is_loading: bool,
}

#[function_component]
fn HelloWorld(props: &Props) -> Html {
    html! { <>{"Am I loading? - "}{props.is_loading.clone()}</> }
}

// Then supply the prop
#[function_component]
fn App() -> Html {
    html! {<HelloWorld is_loading={true} />}
}

```

  </TabItem>
  <TabItem value="no-props" label="No Props">

```rust
use yew::{function_component, html, Html};






#[function_component]
fn HelloWorld() -> Html {
    html! { "Hello world" }
}

// No props to supply
#[function_component]
fn App() -> Html {
    html! {<HelloWorld />}
}

```

  </TabItem>
</Tabs>

## Derive macro field attributes

When deriving `Properties` all fields are required by default.
The following attributes allow you to give your props default values which will be used when parent has not set them.

:::tip
Attributes aren't visible in Rustdoc generated documentation.
The doc strings of your properties should mention whether a prop is optional and if it has a special default value.
:::

<Tabs>
  <TabItem value="prop_or_default" label="#[prop_or_default]">

Initialize the prop value with the default value of the field's type using the `Default` trait.

```rust
use yew::{function_component, html, Html, Properties};

#[derive(Properties, PartialEq)]
pub struct Props {
    // highlight-start
    #[prop_or_default]
    // highlight-end
    pub is_loading: bool,
}

#[function_component]
fn HelloWorld(props: &Props) -> Html {
    if props.is_loading.clone() {
        html! { "Loading" }
    } else {
        html! { "Hello world" }
    }
}

// Then use like this with default
#[function_component]
fn Case1() -> Html {
    html! {<HelloWorld />}
}
// Or no override the default
#[function_component]
fn Case2() -> Html {
    html! {<HelloWorld is_loading={true} />}
}
```

  </TabItem>
  <TabItem value="prop_or_value" label="#[prop_or(value)]">

Use `value` to initialize the prop value. `value` can be any expression that returns the field's type.
For example, to default a boolean prop to `true`, use the attribute `#[prop_or(true)]`. The expression
is evaluated when the properties are constructed and no explicit value has been given.

```rust
use yew::{function_component, html, Html, Properties};

#[derive(Properties, PartialEq)]
pub struct Props {
    // highlight-start
    #[prop_or("Bob".to_string())]
    // highlight-end
    pub name: String,
}

#[function_component]
fn HelloWorld(props: &Props) -> Html {
    html! {<>{"Hello world"}{props.name.clone()}</>}
}

// Then use like this with default
#[function_component]
fn Case1() -> Html {
    html! {<HelloWorld />}
}
// Or no override the default
#[function_component]
fn Case2() -> Html {
    html! {<HelloWorld name={"Sam".to_string()} />}
}
```

  </TabItem>
  <TabItem value="prop_or_else_function" label="#[prop_or_else(function)]">

Call `function` to initialize the prop value. `function` should have the signature `FnMut() -> T` where `T` is the field type.
The function is called when no explicit value has been given for that attribute.

```rust
use yew::{function_component, html, Html, Properties};

fn create_default_name() -> String {
    "Bob".to_string()
}

#[derive(Properties, PartialEq)]
pub struct Props {
    // highlight-start
    #[prop_or_else(create_default_name)]
    // highlight-end
    pub name: String,
}

#[function_component]
fn HelloWorld(props: &Props) -> Html {
    html! {<>{"Hello world"}{props.name.clone()}</>}
}

// Then use like this with default
#[function_component]
fn Case1() -> Html {
    html! {<HelloWorld />}
}
// Or no override the default
#[function_component]
fn Case2() -> Html {
    html! {<HelloWorld name={"Sam".to_string()} />}
}
```

  </TabItem>
</Tabs>

## Memory/speed overhead of using Properties

Internally properties are reference counted. This means that only a shared pointer is passed down the component tree for props.
It saves us from the cost of having to clone the entire props, which might be expensive.

:::tip
Make use of `AttrValue` which is our custom type for attribute values instead of defining them as String or another similar type.
:::

## Props macro

The `yew::props!` macro allows you to build properties the same way the `html!` macro does it.

The macro uses the same syntax as a struct expression except that you can't use attributes or a base expression (`Foo { ..base }`).
The type path can either point to the props directly (`path::to::Props`) or the associated properties of a component (`MyComp::Properties`).

```rust
use yew::{function_component, html, Html, Properties, props, virtual_dom::AttrValue};

#[derive(Properties, PartialEq)]
pub struct Props {
    #[prop_or(AttrValue::from("Bob"))]
    pub name: AttrValue,
}

#[function_component]
fn HelloWorld(props: &Props) -> Html {
    html! {<>{"Hello world"}{props.name.clone()}</>}
}

#[function_component]
fn App() -> Html {
    // highlight-start
    let pre_made_props = props! {
        Props {} // Notice we did not need to specify name prop
    };
    // highlight-end
    html! {<HelloWorld ..pre_made_props />}
}
```

## Evaluation Order

Props are evaluated in the order they're specified, as shown by the following example:

```rust
#[derive(yew::Properties, PartialEq)]
struct Props { first: usize, second: usize, last: usize }

fn main() {
    let mut g = 1..=3;
    let props = yew::props!(Props { first: g.next().unwrap(), second: g.next().unwrap(), last: g.next().unwrap() });

    assert_eq!(props.first, 1);
    assert_eq!(props.second, 2);
    assert_eq!(props.last, 3);
}
```

## Anti Patterns

While almost any Rust type can be passed as properties, there are some anti-patterns that should be avoided.
These include, but are not limited to:

1. Using `String` type instead of `AttrValue`. <br />
   **Why is this bad?** `String` can be expensive to clone.
   Cloning is often needed when the prop value is used with hooks and callbacks. `AttrValue` is either
   a reference-counted string (`Rc<str>`) or a `&'static str`, thus very cheap to clone.<br />
   **Note**: `AttrValue` internally is `IString` from [implicit-clone](https://crates.io/crates/implicit-clone)
   See that crate to learn more.
2. Using interior mutability. <br />
   **Why is this bad?** Interior mutability (such as with `RefCell`, `Mutex`, etc.) should
   _generally_ be avoided. It can cause problems with re-renders (Yew doesn't know when state has changed)
   so you may have to manually force a render. Like all things, it has its place. Use it with caution.
3. You tell us. Did you run into an edge-case you wish you knew about earlier? Feel free to create an issue
   or PR a fix to this documentation.
