#[component]Expand description
Helper attribute macro for creating functional components.
§Usage
This macro is used when creating functional components, where the name of the generated component is the item in the attribute. For example,
#[component(Root)]
pub fn render(title: String) {
let text = use_state(String::new);
let on_key = on_key! { [text]
KeyEvent { code: Char(c), .. } => text.mutate(|text| text.push(c)),
KeyEvent { code: Char(c), .. } => text.mutate(|text| text.pop()),
KeyEvent { code: Esc, .. } => event::quit(),
};
render! {
Centered() {
Section(title) {
Text(text: text.get(), on_key)
}
}
}
}constructs a Root component, that can be used in a render! macro.
§Parameters
If the render function contains parameters, these will become parameters to the
generated component. These parameters can later be supplied when using the generated
component in a render! macro. The parameters’ types must implement Default,
as the generated component derives Default. If you need more control over the
default values of the parameters, consider implementing the Component trait instead
of using the #[component(..)] attribute macro.
§Managing State
State in functional components is managed similarly to how they are in React,
using the use_state hook. Refer to the use_state documentation for details.
§Handling Key Events
In functional components, key events are sent to the component at the root of the
returned render! macro invocation. This means that in the example above, the
key event will be sent to an instance of the Centered component. However,
most components forward their key events to their children (especially those that
have only a single child), and therefore the on_key handler could have been
provided to any of the Centered, Section, or Text components above.
§Generics
When requiring generics, for example when accepting a variable number of children, they can be added into the attribute and then used in the parameters. For example:
#[component(Root<const N: usize>)]
pub fn render(title: String, children: Children<N>) {
let text = use_state(String::new);
let on_key = on_key! { [text]
KeyEvent { code: Char(c), .. } => text.mutate(|text| text.push(c)),
KeyEvent { code: Char(c), .. } => text.mutate(|text| text.pop()),
KeyEvent { code: Esc, .. } => event::quit(),
};
render! {
Centered() {
Section(title) {
Text(text: text.get(), on_key)
}
}
}
}§Generated Component
The generated component is a structure that implements the Component trait. It
also has a an associated function new() -> component::Any that is used to create the
component when passing it to Terminal::new(). If the component has parameters,
they will also be parameters to the associated function new()in the same order
they were specified in the render function.
§Nuances
There are a couple of nuances with this macro:
- The visibility of the generated component will be the same as that of the
renderfunction the#[component(..)]attribute is applied to. - The return type to
render(and even the function name itself) are completely ignored. In order to keep things consistent, it’s recommended that the function is calledrenderand the return type is left empty.
Helper attribute macro for creating functional components.
See the documentation in the intuitive crate for details.