Introduction
コンポーネントとは?
コンポーネントは Yew を構成するブロックです。
コンポーネントは状態を管理し、自身を DOM へレンダリングすることができます。
コンポーネントはライフサイクルの機能があるComponent
トレイトを実装することによって作られます。
ライフサイクル
Contribute to our docs:
Add a diagram of the component lifecycle
ライフサイクルのメソッド
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();
}
}
}
}
ライフサイクルメソッドは実装の必要がなく、デフォルトでは何もしません。
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 つの関連型があります: Message
とProperties
で す。
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
メソッドを利用します。