Module freya::_docs::components_and_props
source · Expand description
§Components
Freya apps are composed of different components. Components are defined in the form functions that might receive some input as Props and return the UI as Element.
You can learn more about how the UI is defined in the UI chapter.
This is how a simple root component looks like:
// Usually, the root component of a Freya app is named `app`,
// but it is not a requirement
fn app() -> Element {
rsx!(
label {
"Hello, World!"
}
)
}
This is perfectly fine but we might consider splitting the app in multiple components as it grows. This would allow to have reusable components and also help maintaining and scaling the app.
Lets create a reusable component:
fn app() -> Element {
rsx!(
// By declaring this element using `TextLabel`
// we are creating an instance of that component
TextLabel {
text: "Number 1"
}
label {
"Number 2"
}
// Another instance of the same component
TextLabel {
text: "Number 3"
}
)
}
// Reusable component that we might call as many times we want
#[component]
fn TextLabel(text: String) -> Element {
rsx!(
label {
"{text}"
}
)
}
Notice how we anotate our TextLabel
component with the macro #[component]
, this will transform every argument of the function (just text: String
in this case) to a component prop.
For more complex components you might want to put the props in an external struct intead of using the #[components]
macro:
#[derive(Props, PartialEq, Clone)]
struct TextLabelProps {
text: String
}
fn TextLabel(TextLabelProps { text }: TextLabelProps) -> Element {
rsx!(
label {
"{text}"
}
)
}
§Renders
Components renders are just when a component function runs, this can happen in multiple scanarios:
- The component just got instanciated for the first time
- A signal that this component is reading, got changed
- The component props changed
Note: The naming of
render
might give you the impression that it means the app will effectively rerender again, it has nothing to do with it, in fact, a component might render (run its function) a thousand times but generate the exact same RSX, if that was the case Freya would not render it again.
Consider this simple component:
#[component]
fn CoolComp() -> Element {
let mut count = use_signal(|| 0);
// One run of this function means one render of this component
// So, everytime the `count` signal is mutated, the component rerenders/is recalled.
rsx!(
label {
// Update the signal value
onclick: move |_| count += 1,
// By embedding the count in this text the component is subscribed to any change of the `count` siganal
"Increase {count}"
}
)
}