--- obj: concept website: https://dioxuslabs.com repo: https://github.com/dioxuslabs/dioxus --- # Dioxus Dioxus is a modern, ergonomic, and high-performance Rust framework for building user interfaces using a Virtual DOM (like React). It supports Web, Desktop, TUI, and Mobile targets using a unified component model. ## Application A dioxus app is just a normal rust application. To get started depend on `dioxus` and start with this `main.rs`: ```rust use dioxus::prelude::*; fn main() { dioxus::launch(App); } #[component] pub fn App() -> Element { rsx! { p { "Hello World!" } } } ``` ## Components (RSX) Dioxus components are Rust functions that return `Element` and use the `rsx!` macro (similar to JSX). The UI is made with HTML and CSS. ```rust use dioxus::prelude::*; #[component] fn App() -> Element { rsx! { div { h1 { "Hello, Dioxus!" } } } } ``` You can define your own components and take values (Props): ```rust #[component] fn MyComp(value: String, myevent: EventHandler, children: Element) -> Element { rsx! { button { onclick: myevent, title: value, {children} } } } // Usage #[component] fn App() -> Element { rsx! { MyComp { // Event Handler onclick: move |_| { println!("Clicked"); }, // Value title: "my_title", // children p { "Hello World" } } } } ``` ### Event Handler Event handling is done inline using closures: ```rust rsx!( button { onclick: move |_| println!("Button clicked"), "Click me" } ) ``` Each event handler receives an event struct (e.g., `MouseEvent`, `FormEvent`). ## Hooks Dioxus has a powerful hook system that allows you to manage state, side effects, and asynchronous operations in your components. With these hooks the UI gets automatically reloaded when needed. > **Warning**: Always call the hooks in the same order or they will not work correctly. This means no hooks in loops or conditions. ### `use_signal` Creates a reactive value that can be read and updated. When the value changes, the component re-renders. ```rust let count = use_signal(|| 0); rsx! { button { onclick: move |_| count.set(count() + 1), "Increment" } p { "Value is {count}" } } ``` ### `use_memo` Computes a derived value that only re-evaluates when its dependencies change. ```rust let doubled = use_memo(|| count() * 2); ``` ### `use_effect` Runs a side effect after the component renders. Useful for operations which should run beside the UI. ```rust use_effect(|| { // Side effect code here }); ``` ### `use_resource` Manages an asynchronous resource, such as data fetched from an API. ```rust let resource = use_resource(|| fetch_data()); ``` ### `use_drop` Registers a callback to be run before the component is removed. Useful for cleaning up side effects. ```rust use_drop(|| { // Cleanup code here }); ``` ## Assets To include assets (like CSS) in our app, you can use the `asset!()` macro. This macro ensures the asset will be included in the final app bundle. ```rust static MY_CSS: Asset = asset!("/assets/main.css"); fn App() -> Element { rsx! { document::Stylesheet { href: MY_CSS } } } ``` ## Routing You can have different routes in your app using dioxus router. To use the router enable the `router` feature in the `dioxus` crate. **Define the routes**: ```rust // All of our routes will be a variant of this Route enum #[derive(Routable, PartialEq, Clone)] enum Route { // if the current location is "/home", render the Home component #[route("/home")] Home {}, // if the current location is "/blog", render the Blog component #[route("/blog")] Blog {}, } fn Home() -> Element { todo!() } fn Blog() -> Element { todo!() } ``` To use the router and actually render the routes, add it to your main App component: ```rust fn App() -> Element { rsx! { document::Stylesheet { href: asset!("/assets/main.css") } // Renders the current route Router:: {} } } ``` To move between routes you can either use a `Link` element or the `navigator`: ```rust // Link Element rsx! { Link { to: Route::Home {}, "Go home!" } } // Navigator rsx! { button { onclick: move |_| { let nav = navigator(); // push nav.push(Route::Blog {}); // replace nav.replace(Route::Home {}); // go back nav.go_back(); // go forward nav.go_forward(); }, "Go somewhere" } } ```