What is Dioxus
-
Framework for building cross-platform apps(frontend, backend, mobile apps) with the Rust programming language
Terms
Components = Functions
-
In Dioxus, apps are comprised of individual functions(called Components) that take in some Properties(structures) and render an Element
All Properties(structs) in Dioxus need to derive the Properties trait which requires both Clone and PartialEq
#[component] macro
Dioxus provides the #[component] macro for simplifying how components are defined. This macro converts the parameters of the annotated function into a hidden accompanying struct.
When building apps, you'll frequently use the #[component] macro. When building libraries, we generally suggest deriving Props instead.
Components are rerendered
Just like React, Dioxus will calls component function multiple times throughout its lifecycle
But Why?
it compares the Element returned from the last render against the Element returned in the current render
In Dioxus, re-renders are extremely cheap (much cheaper than React!)
#[derive(Props, PartialEq, Clone)]
struct DogAppProps {
breed: String
}
fn DogApp(props: DogAppProps) -> Element {
// ...
}
// This macro converts the parameters of the annotated function into a hidden accompanying struct
#[component]
fn DogApp(breed: String) -> Element {
// ...
}
rsx! {} macro
-
Dioxus provides the rsx! {} macro for assembling Elements in your app
rsx! {
if show_title {
"title!"
}
ul { //for inside ul
for item in 0..5 {
"{i}"
}
}
for user in users {
div {
key: "{user.id}", //lists
"{user.name}"
}
}
}
Event Handlers
-
Event handlers are used to respond to user actions. For example, an event handler could be triggered when the user
clicks, scrolls, moves the mouse, or types a character.
Event handlers are attached to elements their name usually starts with on- and they accept closures as values.
The closure will be called whenever the event it listens for is triggered and will be passed that event.
Event handlers receive an Event object containing information about the event.
#[component]
fn DogView() -> Element {
// Closure for event handler
let save = move |evt| {
println!("Inside save");
};
rsx! {
div { id: "dogview",
img { src: "https://images.dog.ceo/breeds/pitbull/dog-3981540_1280.jpg" }
}
div { id: "buttons",
button { onclick: save, id: "save", "save!" }
}
}
}
States
-
App is defined as a function of the current state.
As the state changes, the parts of your app that depend on that state will automatically re-run
You can create mutable state in Dioxus with Signals
Local Variables
Signals (local variables)
-
Signals are used to manage states,
Wrap any value inside Signal and do Read/write. There are 2 ways to create signals:
1. Signal::new()
2. use_signal hook (Recommended. cleans the Signal up for you automatically.)
Reactive Primitives
Dioxus, common reactive primitives include:
1. use_state: Manages component state and triggers a re-render when the state changes.
2. use_effect: Executes side effects based on changes to reactive dependencies.
3. use_ref: Maintains mutable references without triggering re-renders
Increment variable on Mouse Click This will display a button. Everytime we click on button a variable(counter) is incremented. ![]()
|
|
Global Variables/Global State
Context
Global Signal
Context | Global Signal |
---|---|
Variable can be declared in 1 function. Value can be assigned to variable there. And variable can be used in other function. App() => Variable Declaration test_ele() => Variable accessed & Used
|
Declare a global variable and use it in any function
|
Creating a Route
-
For example, on web, whenever you visit the /favorites url in your browser, the corresponding Favorites page will load.
- How to achieve this?
// Add the "Router" feature to the Cargo.toml
$ Cargo.toml
[dependencies]
dioxus = { version = "0.6.0", features = ["fullstack", "router"] } # <----- add "router"
// Dioxus router is defined as an enum with the Routable derive attribute
// Whenever someone reaches root(/), DogView component is rendered
$ main.rs
#[derive(Routable, Clone, PartialEq)]
enum Route {
#[route("/")] //route specifics the route's URL
DogView,
}
fn DogView() -> Element { /* */ }
fn main() {
dioxus::launch(app);
}
fn app() -> Element {
rsx! {
// Now render the Route instead of rendering each component seperately
Router:: {}
}
}