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

プロパティは、子コンポーネントと親コンポーネントが互いに通信できるようにします。
各コンポーネントには、親から渡されるものを記述する関連付けられたプロパティタイプがあります。
理論的には、これは `Properties` trait を実装する任意のタイプにすることができますが、実際には
各フィールドがプロパティを表す構造体以外にする理由はありません。

## マクロの継承

`Properties`を自分で実装しようとせず、代わりに`#[derive(Properties)]`を使ってください。
`Properties`を継承した型は`PartialEq`も実装していなければいけません。

### フィールド属性

デフォルトでは、`Properties` を導出する構造体内のフィールドは必須です。
以下の属性を使うと、props に初期値を与えることができ、他の値に設定されない限りこの値が使用されます。

:::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.
:::

#### `#[prop_or_default]`

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

#### `#[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)]`.

#### `#[prop_or_else(function)]`

Call `function` to initialize the prop value. `function` should have the signature `FnMut() -> T` where `T` is the field type.

## `PartialEq`

もし可能なら props で `PartialEq` を継承するのが良いかもしれません。
`PartialEq`を使うことで、不必要な再レンダリングを避けることができます
(これについては、**最適化とベストプラクティス**のセクションで説明しています)。

## プロパティを使用する際のメモリと速度のオーバーヘッド

`Component::view`ではコンポーネントの状態への参照を取り、それを使って `Html` を作成します。
しかし、プロパティは自身の値です。
つまり、それらを作成して子コンポーネントに渡すためには、`view` 関数で提供される参照を所有する必要があるのです。
これは所有する値を取得するためにコンポーネントに渡される参照を暗黙のうちにクローンすることで行われます。

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

## Example

```rust
use yew::Properties;
/// Importing the AttrValue from virtual_dom
use yew::virtual_dom::AttrValue;

#[derive(Clone, PartialEq)]
pub enum LinkColor {
    Blue,
    Red,
    Green,
    Black,
    Purple,
}

fn create_default_link_color() -> LinkColor {
    LinkColor::Blue
}

#[derive(Properties, PartialEq)]
pub struct LinkProps {
    /// The link must have a target.
    href: AttrValue,
    /// Also notice that we are using AttrValue instead of String
    text: AttrValue,
    /// Color of the link. Defaults to `Blue`.
    #[prop_or_else(create_default_link_color)]
    color: LinkColor,
    /// The view function will not specify a size if this is None.
    #[prop_or_default]
    size: Option<u32>,
    /// When the view function does not specify active, it defaults to true.
    #[prop_or(true)]
    active: bool,
}
```

## 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 cannot 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::{props, Properties, virtual_dom::AttrValue};

#[derive(Clone, PartialEq)]
pub enum LinkColor {
    Blue,
    Red,
    Green,
    Black,
    Purple,
}

fn create_default_link_color() -> LinkColor {
    LinkColor::Blue
}

#[derive(Properties, PartialEq)]
pub struct LinkProps {
    /// The link must have a target.
    href: AttrValue,
    /// Also notice that we're using AttrValue instead of String
    text: AttrValue,
    /// Color of the link. Defaults to `Blue`.
    #[prop_or_else(create_default_link_color)]
    color: LinkColor,
    /// The view function will not specify a size if this is None.
    #[prop_or_default]
    size: Option<u32>,
    /// When the view function doesn't specify active, it defaults to true.
    #[prop_or(true)]
    active: bool,
}

impl LinkProps {
    /// Notice that this function receives href and text as String
    /// We can use `AttrValue::from` to convert it to a `AttrValue`
    pub fn new_link_with_size(href: String, text: String, size: u32) -> Self {
        // highlight-start
        props! {LinkProps {
            href: AttrValue::from(href),
            text: AttrValue::from(text),
            size,
        }}
        // highlight-end
    }
}
```
