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

Introduction

コンポーネントとは?

コンポーネントは Yew を構成するブロックです。 コンポーネントは状態を管理し、自身を DOM へレンダリングすることができます。 コンポーネントはライフサイクルの機能があるComponentトレイトを実装することによって作られます。

ライフサイクル

contribute

ライフサイクルのメソッド

Create

コンポーネントが作られると、ComponentLinkと同様に親コンポーネントからプロパティを受け取ります。 プロパティはコンポーネントの状態を初期化するのに使われ、"link"はコールバックを登録したりコンポーネントにメッセージを送るのに使われます。

props と link をコンポーネント構造体に格納するのが一般的です。 例えば:

pub struct MyComponent {
props: Props,
link: ComponentLink<Self>,
}

impl Component for MyComponent {
type Properties = Props;
// ...

fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
MyComponent { props, link }
}

// ...
}

View

コンポーネントはview()メソッドによってレイアウトを宣言します。 Yew はhtml!マクロによって HTML と SVG ノード、リスナー、子コンポーネントを宣言できます。 マクロは React の JSX のような動きをしますが、JavaScript の代わりに Rust の式を用います。

impl Component for MyComponent {
// ...

fn view(&self) -> Html {
let onclick = self.link.callback(|_| Msg::Click);
html! {
<button {onclick}>{ self.props.button_text }</button>
}
}
}

使い方についてはhtml!ガイドをご確認ください。

Rendered

rendered()コンポーネントのライフサイクルのメソッドはview()が処理されたて Yew がコンポーネントをレンダリングした後、 ブラウザがページを更新する前に呼ばれます。 コンポーネントは、コンポーネントが要素をレンダリングした後にのみ実行できるアクションを実行するため、このメソッドを実装したい場合があります。 コンポーネントが初めてレンダリングされたかどうかは first_render パラメータで確認できます。

use stdweb::web::html_element::InputElement;
use stdweb::web::IHtmlElement;
use yew::prelude::*;

pub struct MyComponent {
node_ref: NodeRef,
}

impl Component for MyComponent {
// ...

fn view(&self) -> Html {
html! {
<input ref={self.node_ref.clone()} type="text" />
}
}

fn rendered(&mut self, first_render: bool) {
if first_render {
if let Some(input) = self.node_ref.try_into::<InputElement>() {
input.focus();
}
}
}
}
note

ライフサイクルメソッドは実装の必要がなく、デフォルトでは何もしません。

Update

コンポーネントは動的で、非同期メッセージを受信するために登録することができます。 ライフサイクルメソッド update() はメッセージごとに呼び出されます。 これにより、コンポーネントはメッセージが何であったかに基づいて自身を更新し、自身を再レンダリングする必要があるかどうかを判断することができます。 メッセージは、HTML 要素リスナーによってトリガーされたり、子コンポーネント、エージェント、サービス、または Futures によって送信されたりします。

update()がどのようなのかについての例は以下の通りです:

pub enum Msg {
SetInputEnabled(bool)
}

impl Component for MyComponent {
type Message = Msg;

// ...

fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::SetInputEnabled(enabled) => {
if self.input_enabled != enabled {
self.input_enabled = enabled;
true // Re-render
} else {
false
}
}
}
}
}

Change

コンポーネントは親によって再レンダリングされることがあります。 このような場合、新しいプロパティを受け取り、再レンダリングを選択する可能性があります。 この設計では、プロパティを変更することで、親から子へのコンポーネントの通信が容易になります。

典型的な実装例は以下の通りです:

impl Component for MyComponent {
// ...

fn change(&mut self, props: Self::Properties) -> ShouldRender {
if self.props != props {
self.props = props;
true
} else {
false
}
}
}

Destroy

コンポーネントが DOM からアンマウントされた後、Yew は destroy() ライフサイクルメソッドを呼び出し、必要なクリーンアップ操作をサポートします。 このメソッドはオプションで、デフォルトでは何もしません。

Associated Types

Componentトレイトは 2 つの関連型があります: MessagePropertiesです。

impl Component for MyComponent {
type Message = Msg;
type Properties = Props;

// ...
}

Messageはコンポーネントによって処理され、何らかの副作用を引き起こすことができるさまざまなメッセージを表します。 例えば、API リクエストをトリガーしたり、UI コンポーネントの外観を切り替えたりする Click メッセージがあります。 コンポーネントのモジュールで Msg という名前の列挙型を作成し、それをコンポーネントのメッセージ型として使用するのが一般的です。 "message"を"msg"と省略するのも一般的です。

enum Msg {
Click,
}

Propertiesは、親からコンポーネントに渡される情報を表します。 この型は Properties trait を実装していなければならず(通常はこれを派生させることで)、特定のプロパティが必須かオプションかを指定することができます。 この型は、コンポーネントの作成・更新時に使用されます。 コンポーネントのモジュール内に Props という構造体を作成し、それをコンポーネントの Properties 型として使用するのが一般的です。 ”Properties”を"props"に短縮するのが一般的です。 Props は親コンポーネントから継承されるので、アプリケーションのルートコンポーネントは通常()型のPropertiesを持ちます。 ルートコンポーネントのプロパティを指定したい場合は、App::mount_with_propsメソッドを利用します。