プロパティを設定するとhtml!
の中でコンポーネントを使う際に好きな値を渡したり、渡された値が使えます。
以下は最小のコンポーネントの書き方です。
use yew::prelude::*;
struct MyComponent {}
impl Component for MyComponent {
type Message = ();
type Properties = ();
fn create(_props: Self::Properties, _link: ComponentLink) -> Self {
Self {}
}
fn update(&mut self, _message: Self::Message) -> ShouldRender {
true
}
fn view(&self) -> Html {
html! {
{"Hello Yew"}
}
}
}
これに対して以下の 2 点を修正します。
type Properties
を()
から適当な構造体にするMyComponent
でプロパティ値を保持する
プロパティ構造体
プロパティとなる構造体にはderive
でProperties
(yew::prelude::*
で取り込まれる)とClone
が必要です。
#[derive(Properties, Clone)]
struct Props {
text: String
}
定義した構造体はComponent
の関連型に設定してあげます。
type Properties = Props;
これで<Component text="foo" />
のようにプロパティが渡せるようになりました。
初期設定
これでまでで渡せるようにはなりましたが、まだコンポーネント内では使えません。使えるようにするには、コンポーネント自体の構造体でプロパティの値を保持しなければなりません。
コンポーネント構造体MyComponent
を以下のように修正します。
struct MyComponent {
props: Props;
}
構造体を使うにはインスタンス化しなければなりませんが、それを行うのがcreate
関数です。
create
関数は自身のインスタンスを返すように実装します。また、第 1 引数として関連型に指定したProperties
のインスタンスが渡される為、好きなようにプロパティ値を加工することができます。ただ今は渡ってきたプロパティをprops
にそのまま渡すだけとします。create
関数部分を修正します。
fn create(props: Self::Properties, _link: ComponentLink) -> Self {
Self { props }
}
これでview
メソッドでself.props.text
のようにアクセスできます。
Rc を使う
view
メソッドでプロパティ値を使う際、Copy
トレイトが実装されている値はそのまま使えますが、そうでない場合は値をクローンして所有権が渡るようにしなければなりません。例えば例のtext
ようにString
のclone
メソッドを呼ぶと新しい値が丸々コピーされてしまうので、沢山の子要素で使うなどした場合に無駄が多いです。
このような場合はRc
を使うことでコピーを回避できます。その為に修正することはProperties
のString
をRc<String>
とするだけです。
#[derive(Properties, Clone)]
struct Props {
text: std::rc::Rc
}
あとはこのコンポーネントに値を渡す側のコンポーネントの同じ値もRc<String>
となるようにして渡してあげるのみです。