メインコンテンツまでスキップ
Version: Next

プロパティ (Properties)

note

プロパティ (Properties) は通常 "Props" と略されます。

プロパティ (Properties) はコンポーネントのパラメータであり、Yew はこれらのパラメータを監視できます。

コンポーネントのプロパティで型を使用する前に、その型は Properties トレイトを実装している必要があります。

リアクティブ性

再レンダリング時に、Yew は仮想DOMを調整する際にプロパティが変更されたかどうかを確認し、ネストされたコンポーネントを再レンダリングする必要があるかどうかを判断します。これにより、Yew は非常にリアクティブなフレームワークと見なされます。親コンポーネントからの変更は常に下位に伝播し、ビューはプロパティ/状態からのデータと常に同期します。

tip

まだ チュートリアル を完了していない場合は、このリアクティブ性を自分でテストしてみてください!

派生マクロ

Yew は、構造体に Properties トレイトを簡単に実装できる派生マクロを提供します。

Properties を派生する型は、Yew がデータ比較を行えるように PartialEq も実装している必要があります。

use yew::Properties;

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

関数コンポーネントでの使用

属性 #[function_component] は、関数の引数で Props を選択的に受け取ることを可能にします。それらを提供するには、html! マクロ内の属性を通じて割り当てることができます。

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

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

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

// そしてプロパティを提供します
#[function_component]
fn App() -> Html {
html! { <HelloWorld is_loading=true /> }
}

派生マクロフィールド属性

Properties を派生する際、デフォルトではすべてのフィールドが必須です。

以下の属性を使用すると、親コンポーネントがそれらを設定しなかった場合にデフォルト値を提供することができます。

tip

属性は Rustdoc によって生成されたドキュメントには表示されません。属性のドキュメント文字列には、その属性がオプションであるかどうか、および特定のデフォルト値があるかどうかを記載する必要があります。

Default トレイトを使用して、フィールド型のデフォルト値でプロパティ値を初期化します。

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

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

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

// デフォルト値を使用する
#[function_component]
fn Case1() -> Html {
html! { <HelloWorld /> }
}
// またはデフォルト値を上書きしない
#[function_component]
fn Case2() -> Html {
html! { <HelloWorld is_loading=true /> }
}

Properties のパフォーマンスオーバーヘッド

内部プロパティは参照カウントされたスマートポインタとして渡されます。これにより、コンポーネントツリー内のプロパティに対して共有ポインタが1つだけ渡されるため、プロパティ全体をクローンする高コストを節約できます。

tip

AttrValue はプロパティ値に使用するカスタムタイプであり、これにより String やその他のクローンコストが高いタイプとして定義する必要がなくなります。

Props マクロ

yew::props! マクロを使用すると、html! マクロと同じ方法でプロパティを構築できます。

このマクロは構造体の式と同じ構文を使用しますが、プロパティや基本式 (Foo { ..base }) を使用することはできません。タイプパスはプロパティ (path::to::Props) に直接指すことも、コンポーネントの関連プロパティ (MyComp::Properties) に指すこともできます。

use yew::prelude::*;

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

#[function_component]
fn Hello(&Props { is_loading, ref name }: &Props) -> Html {
if is_loading {
html! { "Loading" }
} else {
html! { <>{"Hello "}{name}</> }
}
}

#[function_component]
fn App() -> Html {
let pre_made_props = yew::props! {
Props {} // 名前属性を指定する必要はありません
};
html! { <Hello ..pre_made_props /> }
}

自動生成プロパティ (yew-autoprops)

開発プロセスを簡素化するために、#[autoprops] マクロ(yew-autoprops パッケージから)を使用して Properties 構造体を自動生成することもできます。

use yew::prelude::*;
use yew_autoprops::autoprops;

// #[autoprops] マクロは #[function_component] の前に配置する必要があります。順序が重要です。
#[autoprops]
#[function_component]
fn Greetings(
#[prop_or_default]
is_loading: bool,
#[prop_or(AttrValue::Static("Hello"))]
message: &AttrValue,
#[prop_or(AttrValue::Static("World"))]
name: &AttrValue,
) -> Html {
if is_loading {
html! { "Loading" }
} else {
html! { <>{message}{" "}{name}</> }
}
}

// 構造体 "GreetingsProps" は自動的に生成されます。
//
// `is_loading` は値としてコンポーネントに渡され、`message` と `name` は定義に先行する `&` があるため参照として渡されます。

評価順序

属性は指定された順序で評価されます。以下の例を参照してください:

#[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);
}

アンチパターン

ほとんどのRust型はプロパティとして渡すことができますが、避けるべきアンチパターンがいくつかあります。これらには以下が含まれますが、これに限定されません:

  1. String 型を AttrValue の代わりに使用する。
    なぜ悪いのか? String のクローンは高コストです。プロパティ値がフックやコールバックと一緒に使用される場合、通常クローンが必要です。AttrValue は参照カウントされた文字列 (Rc<str>) または &'static str であり、非常に安価にクローンできます。
    注意AttrValue は内部的には implicit-clone からの IString です。詳細はそのパッケージを参照してください。
  2. 内部可変性を使用する。
    なぜ悪いのか? 内部可変性(例えば RefCellMutex など)は 通常 避けるべきです。これにより再レンダリングの問題が発生する可能性があり(Yewは状態が変更されたことを認識しません)、手動で再レンダリングを強制する必要があるかもしれません。すべてのものと同様に、適切な使用場所があります。慎重に使用してください。
  3. Vec 型を IArray の代わりに使用する。
    なぜ悪いのか? VecString と同様にクローンのコストが高いです。IArray は参照カウントされたスライス (Rc<T>) または &'static [T] であり、非常に安価にクローンできます。
    注意IArrayimplicit-clone からインポートできます。詳細はそのパッケージを参照してください。
  4. 新しい発見があるかもしれません。早く知っておきたかったエッジケースに遭遇しましたか?問題を作成するか、このドキュメントに修正のPRを提供してください。

yew-autoprops

yew-autoprops は実験的なパッケージで、関数の引数に基づいて動的にProps構造体を作成することを可能にします。プロパティ構造体が再利用されない場合、これは有用かもしれません。