This PR contains just the breaking changes required for the upcoming store implementation. It adds two new primitives: Mutable mapped signals (without a different subscriber list). This lets you scope a writable value and pass it to a child component. It requires two closures to map the immutable and mutable references to the inner signal. With stores, these closures will be derived Boxed readable and writable values (ReadSignal, and WriteSignal). Any readable or writable types can be converted to a read signal or write signal with the boxed method or built in types are automatically converted into the boxed variants when passing into props * map signals mutably * boxed signals * remove mutable borrow type from boxed writable * improve map mut example * restore boxed_mut helper * make boxed readable/writable types copy * Move away from the ReadOnlySignal alias in examples * automatically convert Write * Fix some tests * ReadSignal and WriteSignal * move read only signal alias * make maps copy * store prototype * implement derive macro * Handle generics in the derive macro * Make Selector boxable * derive boxed conversion * Get rid of store type * Remove hardcoded type from derive macro * selector -> store * Refactor store implementation * more vec methods * todo mvc store example * Implement Storable for HashMap * fix write * restore sorting logic in todomvc * derive readable and writable * improve todomvc store example * Result store * Option store * collect dead subscribers * fix clippy and formatting * recognize some common foreign types automatically * fix foreign stores in props * slice and array selectors * clean up store example * remove stores * writable is child owned * fix typo * fix clippy * fix doc tests
Dioxus Router
Website | Guides | API Docs | Chat
Overview
Dioxus Router is a first-party Router for all your Dioxus Apps. It provides an interface similar to React Router, but takes advantage of types for more expressiveness.
use dioxus::prelude::*;
use std::str::FromStr;
#[rustfmt::skip]
#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
#[nest("/blog")]
#[layout(Blog)]
#[route("/")]
BlogList {},
#[route("/:blog_id")]
BlogPost { blog_id: usize },
#[end_layout]
#[end_nest]
#[route("/")]
Index {},
}
#[component]
fn App() -> Element {
rsx! {
Router::<Route> { }
}
}
#[component]
fn Index() -> Element {
rsx! {
h1 { "Index" }
Link {
to: Route::BlogList {},
"Go to the blog"
}
}
}
#[component]
fn Blog() -> Element {
rsx! {
h1 { "Blog" }
Outlet::<Route> { }
}
}
#[component]
fn BlogList() -> Element {
rsx! {
h2 { "List of blog posts" }
Link {
to: Route::BlogPost { blog_id: 0 },
"Blog post 1"
}
Link {
to: Route::BlogPost { blog_id: 1 },
"Blog post 2"
}
}
}
#[component]
fn BlogPost(blog_id: usize) -> Element {
rsx! {
h2 { "Blog Post" }
}
}
You need to enable the right features for the platform you're targeting since these are not determined automatically!
Bundle Splitting
The Dioxus Router supports automatic bundle splitting along route variants. To enable this, you need to manually turn on the wasm-split feature explicitly on the dioxus-router crate:
[dependencies]
dioxus = { version = "*", features = ["router", "wasm-split"] }
dioxus-router = { version = "*", features = ["wasm-split"] }
Note that wasm-split must also be turned on in dioxus since the macro uses the re-exported wasm-split from the dioxus prelude.
Enabling splitting disconnects the call graph, meaning if you try to run your app with a normal dx serve, it won't work. When running with router splitting, you need to pass --experimental-wasm-split.
dx serve --experimental-wasm-split
In practice, we recommend passing dioxus-router?/wasm-split as a feature only when bundling:
dx bundle --features "dioxus-router?/wasm-split" --experimental-wasm-split
Note that the router will call .suspend() so you should add a SuspenseBoundary above the Outlet to prevent suspending the entire page.
Contributing
- Report issues on our issue tracker.
- Join the discord and ask questions!
License
This project is licensed under the MIT license.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Dioxus by you shall be licensed as MIT without any additional terms or conditions.