Attribute Macro avalanche::component [−][src]
#[component]
Expand description
An attribute macro used to define components.
Basic usage
The macro must be applied to a function that returns a View.
It generates a struct
implementing Component with the name of the input function, and a builder struct.
The function’s name should start with a capital ASCII character.
The function can optionally take parameters. Parameter types must be Clone
and 'static
.
Parameters must have concrete types: they cannot use the impl Trait
syntax. Components cannot be async
or generic.
A component must return a View describing what it will render.
Components are invoked with the same syntax as function calls, except with
the macro !
after the type name:
use avalanche::{component, tracked, View};
use avalanche_web::components::{H1, Text};
const class: &str = "hello-world";
#[component]
pub fn HelloWorld(name: String) -> View {
H1!(
id: class,
class: class,
child: Text!(format!("Hi there, {}!", tracked!(name)))
)
}
In the case of H1
, all of its parameters are optional and have default values, but for components generated by this
macro, all parameters must be provided, or component instantiation will panic at runtime. In the future, this will
instead be a compile-time error.
Note that all macro invocations beginning with a capital ASCII character will be interpreted as component invocations
within the function. If you need to invoke a macro beginning with a capital letter, consider using it with an alias
beginning with _
.
Tracked values
Parameter values are passed into a function with the Tracked wrapper. More details on how that works is found in the tracked macro documentation.
Avoid side effects and mutability
avalanche
considers a parameter updated if one of the parameters or hooks that influence it change, but
a function like rand::thread_rng has a different value on every call
despite having no parameter or hook dependencies.
Using values from functions and methods that are not pure or mutate values will lead to missed updates. Instead, create new variables:
use let string = string + " appended"
instead of string += "appended"
.
If you need to use mutation in a component, including interior mutability, use the state hook.
Eschew third-party macros
Unfortunately, macros are syntax extensions and component
cannot keep track of tracked variables in most of them.
All std
macros (like vec! and format!) and avalanche
macros (like enclose!())
work well, but any others may lead to parameters being incorrectly marked as not updated.