mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
* Make Html a Result. * Fix tests. * Implement Suspense. * Schedule render when suspension is resumed. * Shift children into a detached node. * styled example. * Update wording a little bit. * Move hint to hint. * Add some tests. * Fix clippy. * Add docs. * Add to sidebar. * Fix syntax highlight. * Component -> BaseComponent. * Html -> VNode, HtmlResult = RenderResult<Html>. * Suspendible Function Component. * Add a method to create suspension from futures. * Revert extra changes. * Fix tests. * Update documentation. * Switch to custom trait to make test reliable. * Fix file permission. * Fix docs. * Remove log. * Fix file permission. * Fix component name error. * Make Suspension a future.
143 lines
3.0 KiB
Plaintext
143 lines
3.0 KiB
Plaintext
---
|
|
title: "#[function_component]"
|
|
description: "The #[function_component] attribute"
|
|
---
|
|
|
|
import Tabs from '@theme/Tabs';
|
|
import TabItem from '@theme/TabItem';
|
|
|
|
`#[function_component(_)]` turns a normal Rust function into a function component.
|
|
Functions with the attribute have to return `Html` and may take a single parameter for the type of props the component should accept.
|
|
The parameter type needs to be a reference to a `Properties` type (ex. `props: &MyProps`).
|
|
If the function doesn't have any parameters the resulting component doesn't accept any props.
|
|
|
|
Just mark the component with the attribute. The component will be named after the function.
|
|
|
|
```rust
|
|
use yew::{function_component, html, Html};
|
|
|
|
#[function_component]
|
|
pub fn ChatContainer() -> Html {
|
|
html! {
|
|
// chat container impl
|
|
}
|
|
}
|
|
|
|
html! {
|
|
<ChatContainer />
|
|
};
|
|
```
|
|
|
|
## Specifying a custom component name
|
|
|
|
You need to provide a name as an input to the attribute which will be the identifier of the component.
|
|
Assuming you have a function called `chat_container` and you add the attribute `#[function_component(ChatContainer)]` you can use the component like this:
|
|
|
|
```rust
|
|
use yew::{function_component, html, Html};
|
|
|
|
#[function_component(ChatContainer)]
|
|
pub fn chat_container() -> Html {
|
|
html! {
|
|
// chat container impl
|
|
}
|
|
}
|
|
|
|
html! {
|
|
<ChatContainer />
|
|
};
|
|
```
|
|
|
|
## Example
|
|
|
|
<Tabs>
|
|
<TabItem value="With props" label="With props">
|
|
|
|
```rust
|
|
use yew::{function_component, html, Properties, Html};
|
|
|
|
#[derive(Properties, PartialEq)]
|
|
pub struct RenderedAtProps {
|
|
pub time: String,
|
|
}
|
|
|
|
#[function_component]
|
|
pub fn RenderedAt(props: &RenderedAtProps) -> Html {
|
|
html! {
|
|
<p>
|
|
<b>{ "Rendered at: " }</b>
|
|
{ &props.time }
|
|
</p>
|
|
}
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="Without props" label="Without props">
|
|
|
|
```rust
|
|
use yew::{function_component, html, use_state, Callback, Html};
|
|
|
|
#[function_component]
|
|
fn App() -> Html {
|
|
let counter = use_state(|| 0);
|
|
|
|
let onclick = {
|
|
let counter = counter.clone();
|
|
Callback::from(move |_| counter.set(*counter + 1))
|
|
};
|
|
|
|
html! {
|
|
<div>
|
|
<button {onclick}>{ "Increment value" }</button>
|
|
<p>
|
|
<b>{ "Current value: " }</b>
|
|
{ *counter }
|
|
</p>
|
|
</div>
|
|
}
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
## Generic function components
|
|
|
|
The `#[function_component(_)]` attribute also works with generic functions for creating generic components.
|
|
|
|
```rust title=my_generic_component.rs
|
|
use std::fmt::Display;
|
|
use yew::{function_component, html, Properties, Html};
|
|
|
|
#[derive(Properties, PartialEq)]
|
|
pub struct Props<T>
|
|
where
|
|
T: PartialEq,
|
|
{
|
|
data: T,
|
|
}
|
|
|
|
#[function_component]
|
|
pub fn MyGenericComponent<T>(props: &Props<T>) -> Html
|
|
where
|
|
T: PartialEq + Display,
|
|
{
|
|
html! {
|
|
<p>
|
|
{ &props.data }
|
|
</p>
|
|
}
|
|
}
|
|
|
|
// used like this
|
|
html! {
|
|
<MyGenericComponent<i32> data=123 />
|
|
};
|
|
|
|
// or
|
|
html! {
|
|
<MyGenericComponent<String> data={"foo".to_string()} />
|
|
};
|
|
```
|